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