Re: Scalable tcp server
- From: "shakahshakah@xxxxxxxxx" <shakahshakah@xxxxxxxxx>
- Date: Fri, 13 Jul 2007 13:13:30 -0000
Ignoring the issue of trying to send structs over a socket & the
Sleep() call, shouldn't your loop be something along the lines of the
following to handle a possible incomplete read of HEADER on your call
to Recv()?
// Peek for data
int nReadSoFar = 0 ;
while(1) {
if ((ret = m_Socket.Recv(
((char *) &H) + nReadSoFar
,sizeof(H)-nReadSoFar
,MSG_PEEK)) == SOCKET_ERROR)
return false;
// See if client is disconnected
if (ret == 0) return false;
nReadSoFar += ret ;
if(nReadSoFar >= (int) sizeof(NH)) {
break ;
}
Sleep(5);
}
On Jul 13, 8:55 am, h...@xxxxxxxxxxxxxxx wrote:
Thanks to everyone who has answered this so far.
As per suggestions I did some profiling and with a few small patches I
managed to boost the speed quite a bit. These patches were some
useless wait's here and there and some improvements with a little bit
of caching.
However now with those patches done I hit a new problem. Once in a
while I get errors on the client side and things just stop working.
This problem is *only* happening when I perform stress tests with
multiple socket connections.
I have identified it to be this piece of code on the client:
bool Csocket::SafeRecv()
{
int nIndex = 0;
int nLeft;
int ret;
HEADER H;
// Peek for data
do
{
if ((ret = m_Socket.Recv(&H, sizeof(H), MSG_PEEK)) ==
SOCKET_ERROR)
return false;
// See if client is disconnected
if (ret == 0) return false;
Sleep(5);
} while (ret < (int) sizeof(NH));
// The header has been received and tells you how much data is left
to receive.
nLeft = ENDIAN(H.lLength);
ResizeMemory(nLeft);
// Get the rest
while (nLeft > 0)
{
ret = m_Socket.Recv(&m_pBuffer[nIndex], nLeft, 0);
// Either the client disconnected or a socket error occured.
if (ret == SOCKET_ERROR) return false;
if (ret == 0) return false;
nLeft -= ret;
nIndex += ret;
}
return true;
}
I should make it clear that SOCKET_ERROR is defined as -1 and that
m_Socket.Recv() is just a wrapper around recv().
In the above code I read the header before reading rest of the data.
This is required in order to read how much more data is missing and
perform some cryptography services which I left out.
I have identified that something weird is going on with msg_peek since
"if (ret == 0) return false;" sometimes gets invoked. This means that
the server should have dropped the client connection but this is not
the case. I know that the server didn't do that just for the fun of
it.
Can anyone propose a better/ more safe way of achiving the same as
above?
What I want is to read the network header as 1 recv() before reading
rest of the data. This means that I'd like to wait on the client side
until I know that there is enough data to be read.
Thanks.
-- Henrik
.
- Follow-Ups:
- Re: Scalable tcp server
- From: Henrik Goldman
- Re: Scalable tcp server
- References:
- Scalable tcp server
- From: Henrik Goldman
- Re: Scalable tcp server
- From: hg
- Scalable tcp server
- Prev by Date: Re: Scalable tcp server
- Next by Date: Re: Return status from expect to csh script
- Previous by thread: Re: Scalable tcp server
- Next by thread: Re: Scalable tcp server
- Index(es):
Relevant Pages
|