tcp.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00014 #ifdef ENABLE_NETWORK
00015
00016 #include "../../stdafx.h"
00017 #include "../../debug.h"
00018
00019 #include "tcp.h"
00020
00021 NetworkTCPSocketHandler::NetworkTCPSocketHandler(SOCKET s) :
00022 NetworkSocketHandler(),
00023 packet_queue(NULL), packet_recv(NULL),
00024 sock(s), writable(false)
00025 {
00026 }
00027
00028 NetworkTCPSocketHandler::~NetworkTCPSocketHandler()
00029 {
00030 this->CloseConnection();
00031
00032 if (this->sock != INVALID_SOCKET) closesocket(this->sock);
00033 this->sock = INVALID_SOCKET;
00034 }
00035
00036 NetworkRecvStatus NetworkTCPSocketHandler::CloseConnection(bool error)
00037 {
00038 this->writable = false;
00039 NetworkSocketHandler::CloseConnection(error);
00040
00041
00042 while (this->packet_queue != NULL) {
00043 Packet *p = this->packet_queue->next;
00044 delete this->packet_queue;
00045 this->packet_queue = p;
00046 }
00047 delete this->packet_recv;
00048 this->packet_recv = NULL;
00049
00050 return NETWORK_RECV_STATUS_OKAY;
00051 }
00052
00059 void NetworkTCPSocketHandler::Send_Packet(Packet *packet)
00060 {
00061 Packet *p;
00062 assert(packet != NULL);
00063
00064 packet->PrepareToSend();
00065
00066
00067 p = this->packet_queue;
00068 if (p == NULL) {
00069
00070 this->packet_queue = packet;
00071 } else {
00072
00073 while (p->next != NULL) p = p->next;
00074 p->next = packet;
00075 }
00076 }
00077
00086 bool NetworkTCPSocketHandler::Send_Packets(bool closing_down)
00087 {
00088 ssize_t res;
00089 Packet *p;
00090
00091
00092 if (!this->writable) return false;
00093 if (!this->IsConnected()) return false;
00094
00095 p = this->packet_queue;
00096 while (p != NULL) {
00097 res = send(this->sock, (const char*)p->buffer + p->pos, p->size - p->pos, 0);
00098 if (res == -1) {
00099 int err = GET_LAST_ERROR();
00100 if (err != EWOULDBLOCK) {
00101
00102 if (!closing_down) {
00103 DEBUG(net, 0, "send failed with error %d", err);
00104 this->CloseConnection();
00105 }
00106 return false;
00107 }
00108 return true;
00109 }
00110 if (res == 0) {
00111
00112 if (!closing_down) this->CloseConnection();
00113 return false;
00114 }
00115
00116 p->pos += res;
00117
00118
00119 if (p->pos == p->size) {
00120
00121 this->packet_queue = p->next;
00122 delete p;
00123 p = this->packet_queue;
00124 } else {
00125 return true;
00126 }
00127 }
00128
00129 return true;
00130 }
00131
00137 Packet *NetworkTCPSocketHandler::Recv_Packet()
00138 {
00139 ssize_t res;
00140
00141 if (!this->IsConnected()) return NULL;
00142
00143 if (this->packet_recv == NULL) {
00144 this->packet_recv = new Packet(this);
00145 }
00146
00147 Packet *p = this->packet_recv;
00148
00149
00150 if (p->pos < sizeof(PacketSize)) {
00151 while (p->pos < sizeof(PacketSize)) {
00152
00153 res = recv(this->sock, (char*)p->buffer + p->pos, sizeof(PacketSize) - p->pos, 0);
00154 if (res == -1) {
00155 int err = GET_LAST_ERROR();
00156 if (err != EWOULDBLOCK) {
00157
00158 if (err != 104) DEBUG(net, 0, "recv failed with error %d", err);
00159 this->CloseConnection();
00160 return NULL;
00161 }
00162
00163 return NULL;
00164 }
00165 if (res == 0) {
00166
00167 this->CloseConnection();
00168 return NULL;
00169 }
00170 p->pos += res;
00171 }
00172
00173
00174 p->ReadRawPacketSize();
00175
00176 if (p->size > SEND_MTU) {
00177 this->CloseConnection();
00178 return NULL;
00179 }
00180 }
00181
00182
00183 while (p->pos < p->size) {
00184 res = recv(this->sock, (char*)p->buffer + p->pos, p->size - p->pos, 0);
00185 if (res == -1) {
00186 int err = GET_LAST_ERROR();
00187 if (err != EWOULDBLOCK) {
00188
00189 if (err != 104) DEBUG(net, 0, "recv failed with error %d", err);
00190 this->CloseConnection();
00191 return NULL;
00192 }
00193
00194 return NULL;
00195 }
00196 if (res == 0) {
00197
00198 this->CloseConnection();
00199 return NULL;
00200 }
00201
00202 p->pos += res;
00203 }
00204
00205
00206 this->packet_recv = NULL;
00207
00208 p->PrepareToRead();
00209 return p;
00210 }
00211
00212 bool NetworkTCPSocketHandler::IsPacketQueueEmpty()
00213 {
00214 return this->packet_queue == NULL;
00215 }
00216
00217 #endif