(svn r8525) -Codechange: make NetworkSend_Packet(s) and NetworkRecv_Packet functions of NetworkTCPSocketHandler.

This commit is contained in:
rubidium
2007-02-01 23:50:15 +00:00
parent 4ebb009ab4
commit 59f4f056df
5 changed files with 111 additions and 102 deletions

View File

@@ -38,6 +38,28 @@ void NetworkTCPSocketHandler::Initialize()
this->command_queue = NULL;
}
void NetworkTCPSocketHandler::Destroy()
{
closesocket(this->sock);
this->writable = false;
this->has_quit = true;
/* Free all pending and partially received packets */
while (this->packet_queue != NULL) {
Packet *p = this->packet_queue->next;
delete this->packet_queue;
this->packet_queue = p;
}
delete this->packet_recv;
this->packet_recv = NULL;
while (this->command_queue != NULL) {
CommandPacket *p = this->command_queue->next;
free(this->command_queue);
this->command_queue = p;
}
}
/**
* Functions to help NetworkRecv_Packet/NetworkSend_Packet a bit
* A socket can make errors. When that happens this handles what to do.
@@ -67,9 +89,8 @@ NetworkRecvStatus NetworkTCPSocketHandler::CloseConnection()
* soon as possible. This is the next tick, or maybe one tick later
* if the OS-network-buffer is full)
* @param packet the packet to send
* @param cs the client to send to
*/
void NetworkSend_Packet(Packet *packet, NetworkTCPSocketHandler *cs)
void NetworkTCPSocketHandler::Send_Packet(Packet *packet)
{
Packet *p;
assert(packet != NULL);
@@ -77,10 +98,10 @@ void NetworkSend_Packet(Packet *packet, NetworkTCPSocketHandler *cs)
packet->PrepareToSend();
/* Locate last packet buffered for the client */
p = cs->packet_queue;
p = this->packet_queue;
if (p == NULL) {
/* No packets yet */
cs->packet_queue = packet;
this->packet_queue = packet;
} else {
/* Skip to the last packet */
while (p->next != NULL) p = p->next;
@@ -94,33 +115,32 @@ void NetworkSend_Packet(Packet *packet, NetworkTCPSocketHandler *cs)
* 2) the OS reports back that it can not send any more
* data right now (full network-buffer, it happens ;))
* 3) sending took too long
* @param cs the client to send the packets for
*/
bool NetworkSend_Packets(NetworkTCPSocketHandler *cs)
bool NetworkTCPSocketHandler::Send_Packets()
{
ssize_t res;
Packet *p;
/* We can not write to this socket!! */
if (!cs->writable) return false;
if (!cs->IsConnected()) return false;
if (!this->writable) return false;
if (!this->IsConnected()) return false;
p = cs->packet_queue;
p = this->packet_queue;
while (p != NULL) {
res = send(cs->sock, (const char*)p->buffer + p->pos, p->size - p->pos, 0);
res = send(this->sock, (const char*)p->buffer + p->pos, p->size - p->pos, 0);
if (res == -1) {
int err = GET_LAST_ERROR();
if (err != EWOULDBLOCK) {
/* Something went wrong.. close client! */
DEBUG(net, 0, "send failed with error %d", err);
cs->CloseConnection();
this->CloseConnection();
return false;
}
return true;
}
if (res == 0) {
/* Client/server has left us :( */
cs->CloseConnection();
this->CloseConnection();
return false;
}
@@ -129,9 +149,9 @@ bool NetworkSend_Packets(NetworkTCPSocketHandler *cs)
/* Is this packet sent? */
if (p->pos == p->size) {
/* Go to the next packet */
cs->packet_queue = p->next;
this->packet_queue = p->next;
delete p;
p = cs->packet_queue;
p = this->packet_queue;
} else {
return true;
}
@@ -142,37 +162,36 @@ bool NetworkSend_Packets(NetworkTCPSocketHandler *cs)
/**
* Receives a packet for the given client
* @param cs the client to (try to) receive a packet for
* @param status the variable to store the status into
* @return the received packet (or NULL when it didn't receive one)
*/
Packet *NetworkRecv_Packet(NetworkTCPSocketHandler *cs, NetworkRecvStatus *status)
Packet *NetworkTCPSocketHandler::Recv_Packet(NetworkRecvStatus *status)
{
ssize_t res;
Packet *p;
*status = NETWORK_RECV_STATUS_OKAY;
if (!cs->IsConnected()) return NULL;
if (!this->IsConnected()) return NULL;
if (cs->packet_recv == NULL) {
cs->packet_recv = new Packet(cs);
if (cs->packet_recv == NULL) error("Failed to allocate packet");
if (this->packet_recv == NULL) {
this->packet_recv = new Packet(this);
if (this->packet_recv == NULL) error("Failed to allocate packet");
}
p = cs->packet_recv;
p = this->packet_recv;
/* Read packet size */
if (p->pos < sizeof(PacketSize)) {
while (p->pos < sizeof(PacketSize)) {
/* Read the size of the packet */
res = recv(cs->sock, (char*)p->buffer + p->pos, sizeof(PacketSize) - p->pos, 0);
res = recv(this->sock, (char*)p->buffer + p->pos, sizeof(PacketSize) - p->pos, 0);
if (res == -1) {
int err = GET_LAST_ERROR();
if (err != EWOULDBLOCK) {
/* Something went wrong... (104 is connection reset by peer) */
if (err != 104) DEBUG(net, 0, "recv failed with error %d", err);
*status = cs->CloseConnection();
*status = this->CloseConnection();
return NULL;
}
/* Connection would block, so stop for now */
@@ -180,7 +199,7 @@ Packet *NetworkRecv_Packet(NetworkTCPSocketHandler *cs, NetworkRecvStatus *statu
}
if (res == 0) {
/* Client/server has left */
*status = cs->CloseConnection();
*status = this->CloseConnection();
return NULL;
}
p->pos += res;
@@ -190,20 +209,20 @@ Packet *NetworkRecv_Packet(NetworkTCPSocketHandler *cs, NetworkRecvStatus *statu
p->ReadRawPacketSize();
if (p->size > SEND_MTU) {
*status = cs->CloseConnection();
*status = this->CloseConnection();
return NULL;
}
}
/* Read rest of packet */
while (p->pos < p->size) {
res = recv(cs->sock, (char*)p->buffer + p->pos, p->size - p->pos, 0);
res = recv(this->sock, (char*)p->buffer + p->pos, p->size - p->pos, 0);
if (res == -1) {
int err = GET_LAST_ERROR();
if (err != EWOULDBLOCK) {
/* Something went wrong... (104 is connection reset by peer) */
if (err != 104) DEBUG(net, 0, "recv failed with error %d", err);
*status = cs->CloseConnection();
*status = this->CloseConnection();
return NULL;
}
/* Connection would block */
@@ -211,7 +230,7 @@ Packet *NetworkRecv_Packet(NetworkTCPSocketHandler *cs, NetworkRecvStatus *statu
}
if (res == 0) {
/* Client/server has left */
*status = cs->CloseConnection();
*status = this->CloseConnection();
return NULL;
}
@@ -219,10 +238,16 @@ Packet *NetworkRecv_Packet(NetworkTCPSocketHandler *cs, NetworkRecvStatus *statu
}
/* Prepare for receiving a new packet */
cs->packet_recv = NULL;
this->packet_recv = NULL;
p->PrepareToRead();
return p;
}
bool NetworkTCPSocketHandler::IsPacketQueueEmpty()
{
return this->packet_queue == NULL;
}
#endif /* ENABLE_NETWORK */