diff --git a/src/network/network.cpp b/src/network/network.cpp index 988a2d53b5..57523bfd8f 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -170,6 +170,9 @@ int NetworkConnection::ReadPacket() inboundpacket.transferred += readBytes; if (inboundpacket.transferred == sizeof(inboundpacket.size)) { inboundpacket.size = ntohs(inboundpacket.size); + if(inboundpacket.size == 0){ // Can't have a size 0 packet + return NETWORK_DISCONNECTED; + } inboundpacket.data->resize(inboundpacket.size); } } else { @@ -192,30 +195,23 @@ int NetworkConnection::ReadPacket() return NETWORK_MORE_DATA; } -int NetworkConnection::SendPacket(NetworkPacket& packet) +bool NetworkConnection::SendPacket(NetworkPacket& packet) { + uint16 sizen = htons(packet.size); + std::vector tosend; + tosend.insert(tosend.end(), (uint8*)&sizen, (uint8*)&sizen + sizeof(sizen)); + tosend.insert(tosend.end(), packet.data->begin(), packet.data->end()); while (1) { - if (packet.transferred < sizeof(packet.size)) { - // send packet size - uint16 size = htons(packet.size); - int sentBytes = send(socket, &((char*)&size)[packet.transferred], sizeof(size) - packet.transferred, 0); - if (sentBytes == SOCKET_ERROR) { - return 0; - } - packet.transferred += sentBytes; - } else { - // send packet data - int sentBytes = send(socket, (const char*)&packet.GetData()[packet.transferred - sizeof(packet.size)], packet.data->size(), 0); - if (sentBytes == SOCKET_ERROR) { - return 0; - } - packet.transferred += sentBytes; - if (packet.transferred == sizeof(packet.size) + packet.data->size()) { - return 1; - } + int sentBytes = send(socket, (const char*)&tosend[packet.transferred], tosend.size() - packet.transferred, 0); + if (sentBytes == SOCKET_ERROR) { + return false; + } + packet.transferred += sentBytes; + if (packet.transferred == tosend.size()) { + return true; } } - return 0; + return false; } void NetworkConnection::QueuePacket(std::unique_ptr packet) @@ -233,6 +229,11 @@ void NetworkConnection::SendQueuedPackets() } } +bool NetworkConnection::SetTCPNoDelay(bool on) +{ + return setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, (const char*)&on, sizeof(on)) == 0; +} + Network::Network() { wsa_initialized = false; @@ -330,6 +331,7 @@ bool Network::BeginClient(const char* host, unsigned short port) } server_connection.socket = server_socket; + server_connection.SetTCPNoDelay(true); mode = NETWORK_MODE_CLIENT; @@ -703,6 +705,7 @@ void Network::AddClient(SOCKET socket) { auto connection = std::unique_ptr(new NetworkConnection); // change to make_unique in c++14 connection->socket = socket; + connection->SetTCPNoDelay(true); client_connection_list.push_back(std::move(connection)); } diff --git a/src/network/network.h b/src/network/network.h index 55826d0668..bd7015897f 100644 --- a/src/network/network.h +++ b/src/network/network.h @@ -84,7 +84,7 @@ public: void Write(uint8* bytes, unsigned int size); void WriteString(const char* string); template - NetworkPacket& operator>>(T& value) { if (read + sizeof(value) > size) { value = 0; } else { value = ByteSwapBE(*((T*)&GetData()[read])); read += sizeof(value); } return *this; }; + NetworkPacket& operator>>(T& value) { if (read + sizeof(value) > size) { value = 0; } else { value = ByteSwapBE(*((T*)&GetData()[read])); read += sizeof(value); } return *this; } const uint8* Read(unsigned int size); const char* ReadString(); void Clear(); @@ -112,6 +112,7 @@ public: int ReadPacket(); void QueuePacket(std::unique_ptr packet); void SendQueuedPackets(); + bool SetTCPNoDelay(bool on); SOCKET socket; NetworkPacket inboundpacket; @@ -120,7 +121,7 @@ public: uint32 ping_time; private: - int SendPacket(NetworkPacket& packet); + bool SendPacket(NetworkPacket& packet); std::list> outboundpackets; };