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
00088 bool NetworkTCPSocketHandler::Send_Packets(bool closing_down)
00089 {
00090 ssize_t res;
00091 Packet *p;
00092
00093
00094 if (!this->writable) return false;
00095 if (!this->IsConnected()) return false;
00096
00097 p = this->packet_queue;
00098 while (p != NULL) {
00099 res = send(this->sock, (const char*)p->buffer + p->pos, p->size - p->pos, 0);
00100 if (res == -1) {
00101 int err = GET_LAST_ERROR();
00102 if (err != EWOULDBLOCK) {
00103
00104 if (!closing_down) {
00105 DEBUG(net, 0, "send failed with error %d", err);
00106 this->CloseConnection();
00107 }
00108 return false;
00109 }
00110 return true;
00111 }
00112 if (res == 0) {
00113
00114 if (!closing_down) this->CloseConnection();
00115 return false;
00116 }
00117
00118 p->pos += res;
00119
00120
00121 if (p->pos == p->size) {
00122
00123 this->packet_queue = p->next;
00124 delete p;
00125 p = this->packet_queue;
00126 } else {
00127 return true;
00128 }
00129 }
00130
00131 return true;
00132 }
00133
00139 Packet *NetworkTCPSocketHandler::Recv_Packet()
00140 {
00141 ssize_t res;
00142
00143 if (!this->IsConnected()) return NULL;
00144
00145 if (this->packet_recv == NULL) {
00146 this->packet_recv = new Packet(this);
00147 }
00148
00149 Packet *p = this->packet_recv;
00150
00151
00152 if (p->pos < sizeof(PacketSize)) {
00153 while (p->pos < sizeof(PacketSize)) {
00154
00155 res = recv(this->sock, (char*)p->buffer + p->pos, sizeof(PacketSize) - p->pos, 0);
00156 if (res == -1) {
00157 int err = GET_LAST_ERROR();
00158 if (err != EWOULDBLOCK) {
00159
00160 if (err != 104) DEBUG(net, 0, "recv failed with error %d", err);
00161 this->CloseConnection();
00162 return NULL;
00163 }
00164
00165 return NULL;
00166 }
00167 if (res == 0) {
00168
00169 this->CloseConnection();
00170 return NULL;
00171 }
00172 p->pos += res;
00173 }
00174
00175
00176 p->ReadRawPacketSize();
00177
00178 if (p->size > SEND_MTU) {
00179 this->CloseConnection();
00180 return NULL;
00181 }
00182 }
00183
00184
00185 while (p->pos < p->size) {
00186 res = recv(this->sock, (char*)p->buffer + p->pos, p->size - p->pos, 0);
00187 if (res == -1) {
00188 int err = GET_LAST_ERROR();
00189 if (err != EWOULDBLOCK) {
00190
00191 if (err != 104) DEBUG(net, 0, "recv failed with error %d", err);
00192 this->CloseConnection();
00193 return NULL;
00194 }
00195
00196 return NULL;
00197 }
00198 if (res == 0) {
00199
00200 this->CloseConnection();
00201 return NULL;
00202 }
00203
00204 p->pos += res;
00205 }
00206
00207
00208 this->packet_recv = NULL;
00209
00210 p->PrepareToRead();
00211 return p;
00212 }
00213
00214 bool NetworkTCPSocketHandler::IsPacketQueueEmpty()
00215 {
00216 return this->packet_queue == NULL;
00217 }
00218
00219 #endif