Problem with synchronous Socket

  • Thread starter Thread starter billa
  • Start date Start date
B

billa

Hi,

I need to implement a socket server. I am using the following code to
read from the socket.


private int Read(ref byte[] buffer)
{
if (sapRequest.WaitForRequestBytes(socket) == 0)
return 0;

int numBytes = socket.Available;

int numReceived = 0;
buffer = new byte[numBytes];
if (numBytes > 0)
{
numReceived = socket.Receive(buffer, 0, numBytes,
SocketFlags.None);
}

if (numReceived < numBytes)
{
byte[] tempBuffer = new byte[numReceived];

if (numReceived > 0)
{
Buffer.BlockCopy(buffer, 0, tempBuffer, 0, numReceived);
}

buffer = tempBuffer;
}

DWLog.Write(DWLogLevel.Information,"Number of bytes received: " +
numReceived);

return numReceived;
}


As you can see I am also using a method called WaitForRequestBytes.
Here it is:

public int WaitForRequestBytes(Socket socket)
{
int availBytes = 0;

try
{
DWLog.Write(DWLogLevel.Information,"Socket.Available: " +
socket.Available);
if (socket.Available == 0)
{
// poll until there is data
// DWLog.Write(DWLogLevel.Information, "Waiting for
more data. Polling 100ms");
// socket.Poll(10000 /* 100ms */,
SelectMode.SelectRead);

DWLog.Write(DWLogLevel.Information, "Waiting for
more data. Polling 100ms");
socket.Poll(10000 /* 100ms */,
SelectMode.SelectRead);

if (socket.Available == 0 && socket.Connected)
{
DWLog.Write(DWLogLevel.Information,"Waiting for more data.
Polling 1s");
socket.Poll(100000 /* 1s */, SelectMode.SelectRead);
// DWLog.Write(DWLogLevel.Information, "Waiting
for more data. Polling 10sec");
// socket.Poll(10000000 /* 10sec */,
SelectMode.SelectRead);

}
}

availBytes = socket.Available;
DWLog.Write(DWLogLevel.Information,"Bytes available: " +
availBytes);
}
catch
{
}

return availBytes;
}

My problem now is the following. The bytes don´t arrive continuously
from the client. Therefore I introduced the method WaitForRequestBytes
which polls for data. The polling does its job. The polling time is
just enough to give the client enough time to send more data. Now this
approach proves to be a drawback on performance since the polling is
always executed even if there is no more data available from the
client.
For some reason and under certain circumstances socket.Available return
0 even when the client has not yet sent all its data.
Can anyone explain thsi behaviour to me?
Is there a reliable way to determine if all bytes where received from a
client?

I think asyncronous sockets are no solution for me, because I need
control the order of the processing of the sockets.

Thanks for your help.
 
Hi Vadym,

I have tried socket.Receive but the problem there was that it waited
for data until the client went in a timeout and that was definitely
even longer than the polling took.

To answer your question whether I am receiving data from differernt
sockets. I am creating a new socket for each request coming in and
handle that socket connection in a thread. I use the following code:

public void Run()
{
try
{
Thread th = new Thread(new ThreadStart(StartListenThreaded));
th.Start();

}
catch(System.Exception e)
{
}
}


The StartListenThreaded method looks like this:

private void StartListenThreaded()
{
IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
IPEndPoint EndPoint = new IPEndPoint(IPAddress.Any, port);
Socket ss = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);


ss.Bind( EndPoint);
ss.Listen(20);
try
{
while(true)
{
Socket sock = ss.Accept();
Connection con = new Connection(sock);

Thread t = new Thread(new ThreadStart(con.ProcessOneRequest));
t.IsBackground=true;
t.Priority=ThreadPriority.BelowNormal;
t.Start();
}
}
catch (System.Exception e1)
{
}

}

I thought this was a good and performant way to handle the sockets.
What do you think? What do you think about my statement from above
about the socket.Receive problem?

Thanks

billa
 
Hi again Vadym,

I guess I will try the thing with Receive. The problem with it is that
my client does not close the socket. This means that Receive will wait
for data a long time until the client times out. How can I handle this
problem .
Do you also have a solution for this?

Thanks

billa
 
Hello, billa!

b> I guess I will try the thing with Receive. The problem with it is that
b> my client does not close the socket. This means that Receive will wait
b> for data a long time until the client times out. How can I handle this
b> problem .

Use flags that will indicate the end if client message

b> Do you also have a solution for this?

Do you communicate with client using application ( your custom ) protocol?

Generally connection close is not required, however in this case the data passed to and from client is organized according to definite communication protocol. Client & server know the protocol and can communicate using it without closing connection and blockin. For instance, mail and news applications....

--
Regards, Vadym Stetsyak
www: http://vadmyst.blogspot.com
 
Hi Vadym,

That is another problem. I have no control on what the client sends.
Basically it sends HTTP requests. So I can not send any stop flags or
anything like that.
Can I set a timeout on the socket before I use the Receive method? The
socket Receive would then automatically timeout when no further data is
send by the client after a certain time. It something like that
possible?

Thanks billa.
 
Hello, billa!

b> That is another problem. I have no control on what the client sends.
b> Basically it sends HTTP requests. So I can not send any stop flags or
b> anything like that.

Why can't you use HttpWebRequest/HttpWebResponse model for your task?

--
Regards, Vadym Stetsyak
www: http://vadmyst.blogspot.com
 
Back
Top