Timmmm3d
May 8th, 2003, 01:02 PM
OK, here's the situation. I have a game (client-server) which works in linux, but when I try and run it in windows, the networking bit doesn't work.
The specific bit, is in the server (although the client probably doesn't work either, but they are coded symetrically, so I can fix that later). Anyway, the server has a TCP socket - called TCPSocket - which it wants to receive packets on. (I know they definately *are* send correctly).
The packets come as 2 bytes containing the packet length, and the length bytes containing the packet. Here is the code I use to receive it (the socket is non-blocking):
uint16 Length;
int R;
R = recv(TCPSocket, reinterpret_cast<char*>(&Length), 2, MSG_PEEK | MSG_NOSIGNAL | MSG_DONTWAIT);
if (R == 0)
{
throw TException("Client::RecvPacket", "recv() returned 0.", "Connection closed.", "NET_ERROR");
}
else if (R == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK)
{
cout << WSAGetLastError() << endl;
throw TException("Client::RecvPacket", "recv() returned SOCKET_ERROR.", "Connection closed.", "NET_ERROR");
}
else if (R == 2)
{
cout << "Got Length\n";
char* Buffer = new char[Length + 2];
R = recv(TCPSocket, Buffer, Length + 2, MSG_PEEK | MSG_NOSIGNAL | MSG_DONTWAIT);
if (R == 0)
{
delete[] Buffer;
throw TException("Client::RecvPacket::", "recv() returned 0.", "Connection closed.", "NET_ERROR");
}
else if (R == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK)
{
delete[] Buffer;
cout << WSAGetLastError() << endl;
throw TException("Client::RecvPacket", "::recv() returned SOCKET_ERROR.", "Connection closed.", "NET_ERROR");
}
else if (R == Length + 2)
{
recv(TCPSocket, Buffer, Length + 2, MSG_WAITALL | MSG_NOSIGNAL);
TNetwork::Packet P(Buffer + 2, Length);
delete[] Buffer;
return P;
}
else
{
cout << "Only received " << R << " so far. Need " << Length + 2 << endl;
}
delete[] Buffer;
}
else
{
cout << "Only received " << R << " byte of length so far. Need 2\n";
}
Oh yeah, also, 2 bytes containing a UDP port number are exchaned first. That bit works.
After that, the first length it receives it 20 (which is correct), but then the second recv(...PEEK) only ever says there are the 2 bytes of the length available. If I scrap all that and receive bytes one at a time, however, I get them all!
Seems, MSG_PEEK doesn't work properly (or as expected).
Any help anyone.
Thankyou for you time :)
Tim Hutt.
The specific bit, is in the server (although the client probably doesn't work either, but they are coded symetrically, so I can fix that later). Anyway, the server has a TCP socket - called TCPSocket - which it wants to receive packets on. (I know they definately *are* send correctly).
The packets come as 2 bytes containing the packet length, and the length bytes containing the packet. Here is the code I use to receive it (the socket is non-blocking):
uint16 Length;
int R;
R = recv(TCPSocket, reinterpret_cast<char*>(&Length), 2, MSG_PEEK | MSG_NOSIGNAL | MSG_DONTWAIT);
if (R == 0)
{
throw TException("Client::RecvPacket", "recv() returned 0.", "Connection closed.", "NET_ERROR");
}
else if (R == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK)
{
cout << WSAGetLastError() << endl;
throw TException("Client::RecvPacket", "recv() returned SOCKET_ERROR.", "Connection closed.", "NET_ERROR");
}
else if (R == 2)
{
cout << "Got Length\n";
char* Buffer = new char[Length + 2];
R = recv(TCPSocket, Buffer, Length + 2, MSG_PEEK | MSG_NOSIGNAL | MSG_DONTWAIT);
if (R == 0)
{
delete[] Buffer;
throw TException("Client::RecvPacket::", "recv() returned 0.", "Connection closed.", "NET_ERROR");
}
else if (R == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK)
{
delete[] Buffer;
cout << WSAGetLastError() << endl;
throw TException("Client::RecvPacket", "::recv() returned SOCKET_ERROR.", "Connection closed.", "NET_ERROR");
}
else if (R == Length + 2)
{
recv(TCPSocket, Buffer, Length + 2, MSG_WAITALL | MSG_NOSIGNAL);
TNetwork::Packet P(Buffer + 2, Length);
delete[] Buffer;
return P;
}
else
{
cout << "Only received " << R << " so far. Need " << Length + 2 << endl;
}
delete[] Buffer;
}
else
{
cout << "Only received " << R << " byte of length so far. Need 2\n";
}
Oh yeah, also, 2 bytes containing a UDP port number are exchaned first. That bit works.
After that, the first length it receives it 20 (which is correct), but then the second recv(...PEEK) only ever says there are the 2 bytes of the length available. If I scrap all that and receive bytes one at a time, however, I get them all!
Seems, MSG_PEEK doesn't work properly (or as expected).
Any help anyone.
Thankyou for you time :)
Tim Hutt.