Having a problem with some socket code

From: Tony Caduto (acaduto_at_amsoftwaredesign.com)
Date: 08/19/04


Date: Wed, 18 Aug 2004 22:34:18 -0500

Hi,
I am developing a socket server in C# and I want it to be blocking.
Anyway I have it working with threads, as each client connects the socket
spawned from the accept method is sent to a client thread.
In each thread I have a loop like below:

the data_available method is a wrapper around Socket.Poll() so I can use it
in miliseconds instead of micro.
Basicly I read a command via a streamreader and that all works, then
depending on the command I may go into a recieve or send variable length
data method that calls recieve directly to get the size of the data in the
first 4 bytes, then read the rest.
This all works great if I don't use the Poll method to prevent the blocking
read. I don't want it to block on readline because I have other things I
want to do in the loop. I picked up the recievevardata method from Richard
Blum's book C# network programming. Good book by the way :-)

It almost seems like the readline method is causing a timing issue because
if I put a sleep(500) on the client between commands it works with the Poll
(data_available wrapper method)

 public void connection_loop()
   {
   while(true)
   {
    if (fclientsock.data_available(1000) )
    {
     try
     {
      command = sr.ReadLine();
      process_command(command);
      if (command==null)
       break;
     }
     catch(IOException e)
     {
      Console.WriteLine("IO ERROR: "+e.Message);
      break;
     }
     finally
     {
      //ensure all data in the buffer is sent

with the poll method the following function fails to get the correct size in
the first 4 bytes. I need a function like this to be compatible with Indy's
sendstream method which works exactly the same. (Indy is a Borland Delphi
socket library)

public byte[] recievevardata(bool indycompatible)
 {
  int total = 0;
  int recv;

  byte[] datasize = new byte[4];
  recv = fsocket.Receive(datasize,0,4,0);

  int size = BitConverter.ToInt32(datasize,0);
  //needed for compatiblility with Indy's writestream method
  if(indycompatible)
   size = IPAddress.NetworkToHostOrder(size);

  int dataleft = size;
  byte[] data = new byte[size];
  while(total < size)
  {
   recv = fsocket.Receive(data,total,dataleft,0);
   if (recv==0) //disconnect occured while in transfer
   {
    data = Encoding.ASCII.GetBytes("exit ");
    break;
   }
   total += recv;
   dataleft -= recv;
   Thread.Sleep(0); //don't hog the cpu
  }
  return data;

 }

     }
    }

--
Tony Caduto
Inexpensive Corporate Messaging
AM Software Design
http://www.amsoftwaredesign.com


Relevant Pages

  • Re: Interrupting a socket operation from another thread
    ... Using blocking connect, send, recv calls. ... Are you using a dedicated thread per client? ... close the socket handle but this gives a race condition (on unix ... If you want to shutdown the connection the socket refers to, ...
    (comp.programming.threads)
  • Re: How to do Async TCP Listener?
    ... I suspect your listening socket is a "blocking" socket ... If so, your client ...
    (microsoft.public.dotnet.languages.vb)
  • Re: "connect" returns before server "accept"s
    ... > the socket to become write ready, or time out -- which can be INFINITE is you ... writing has precisely the same effect as a blocking connect, ... Of course, if the client sends data before the server calls accept, it ...
    (comp.unix.programmer)
  • [PATCH 0/5] [RFC] AF_RXRPC socket family implementation [try #3]
    ... These patches together supply secure client-side RxRPC connectivity as a Linux ... kernel socket family. ... presentation side is left to the client. ... Each connection goes to a particular "service". ...
    (Linux-Kernel)
  • [PATCH 0/5] [RFC] AF_RXRPC socket family implementation
    ... These patches together supply secure client-side RxRPC connectivity as a Linux ... Make it possible for the client socket to be used to go to more than one ... Each connection goes to a particular "service". ...
    (Linux-Kernel)