c# - TCP Server with bi-directional communication -


i have attempted create tcp service able achieve wish sadly getting stuck @ last hurdle.

the scenario: single server instance running 10 clients connected, client send command, , receive response. working fine. last scenario isn't working

when client issues "update" command, server should send message connected clients need something.


example comms:

1 client          gettime ----->          server client          <----- time is...       server   2 client          update ------>          server client          <------- ack            server client          <------- doupdate       server client b          <------- doupdate       server client c          <------- doupdate       server 

comms 1 abover works, because of call send , call reeive, comms 2 cannot workout how can achieve this, @ least not without opening second port communication isn't ideal.


current attempt based on microsoft article

server

class program {     public static int main(string[] args)     {         asynchronoussocketlistener.startlistening();         return 0;     } } public class stateobject {     // client  socket.     public socket worksocket = null;     // size of receive buffer.     public const int buffersize = 1024;     // receive buffer.     public byte[] buffer = new byte[buffersize];     // received data string.     public stringbuilder sb = new stringbuilder(); }  public class asynchronoussocketlistener {     // thread signal.     public static manualresetevent alldone = new manualresetevent(false);      public static void startlistening()     {         // data buffer incoming data.         //var bytes = new byte[1024];          // establish local endpoint socket.         // dns name of computer         // running listener "host.contoso.com".     //??iphostentry iphostinfo = dns.resolve(dns.gethostname());     //??ipaddress ipaddress = iphostinfo.addresslist[0];     //??ipendpoint localendpoint = new ipendpoint(ipaddress, 3030);      // create tcp/ip socket.     var listener = new socket(addressfamily.internetwork, sockettype.stream, protocoltype.tcp);      // bind socket local endpoint , listen incoming connections.     try     {         listener.bind(new ipendpoint(ipaddress.any, 3030));         //listener.bind(localendpoint);         listener.listen(100);          while (true)         {             // set event nonsignaled state.             alldone.reset();              // start asynchronous socket listen connections.             console.writeline("waiting connection...");             listener.beginaccept((acceptcallback), listener);              // wait until connection made before continuing.             alldone.waitone();         }      }     catch (exception e)     {         console.writeline(e.tostring());     }      console.writeline("\npress enter continue...");     console.read();  }  public static void acceptcallback(iasyncresult ar) {     // signal main thread continue.     alldone.set();      // socket handles client request.     var listener = (socket)ar.asyncstate;     socket handler = listener.endaccept(ar);      // create state object.     var state = new stateobject {worksocket = handler};     handler.beginreceive(state.buffer, 0, stateobject.buffersize, 0, readcallback, state); }  public static void readcallback(iasyncresult ar) {     // retrieve state object , handler socket     // asynchronous state object.     var state = (stateobject)ar.asyncstate;     socket handler = state.worksocket;      // read data client socket.      int bytesread = handler.endreceive(ar);      if (bytesread > 0)     {         // there  might more data, store data received far.         state.sb.append(encoding.ascii.getstring(             state.buffer, 0, bytesread));          // check end-of-file tag. if not there, read          // more data.         var content = state.sb.tostring();         if (content.indexof("<eof>", stringcomparison.ordinal) > -1)         {             // data has been read              // client. display on console.             console.writeline("read {0} bytes socket. \n data : {1}",                 content.length, content);             // echo data client.             send(handler, content);         }         else         {             // not data received. more.             handler.beginreceive(state.buffer, 0, stateobject.buffersize, 0, readcallback, state);         }     } }  private static void send(socket handler, string data) {     // convert string data byte data using ascii encoding.     var bytedata = encoding.ascii.getbytes(data);      // begin sending data remote device.     handler.beginsend(bytedata, 0, bytedata.length, 0, sendcallback, handler); }  private static void sendcallback(iasyncresult ar) {     try     {         // retrieve socket state object.         var handler = (socket)ar.asyncstate;          // complete sending data remote device.         int bytessent = handler.endsend(ar);         console.writeline("sent {0} bytes client.", bytessent);          handler.shutdown(socketshutdown.both);         handler.close();      }     catch (exception e)     {         console.writeline(e.tostring());     } }  /* public static int main(string[] args) {     startlistening();     return 0; }  * */ } 

client code

class program {     public static int main(string[] args)     //static void main(string[] args)     {         console.title = "client ";         asynchronousclient.startclient();         console.readline();         return 0;     } }  public class stateobject { // client socket. public socket worksocket = null; // size of receive buffer. public const int buffersize = 256; // receive buffer. public byte[] buffer = new byte[buffersize]; // received data string. public stringbuilder sb = new stringbuilder(); }  public class asynchronousclient { // port number remote device. private const int port = 3030;  // manualresetevent instances signal completion. private static readonly manualresetevent connectdone =     new manualresetevent(false); private static readonly manualresetevent senddone =     new manualresetevent(false); private static readonly manualresetevent receivedone =     new manualresetevent(false);  // response remote device. private static string _response = string.empty;  public static void startclient() {     // connect remote device.     try     {         // establish remote endpoint socket.         // name of          // remote device "host.contoso.com".         //iphostentry iphostinfo = dns.resolve("host.contoso.com");         //??iphostentry iphostinfo = dns.resolve("localhost");         //??ipaddress ipaddress = iphostinfo.addresslist[0];         //??ipendpoint remoteep = new ipendpoint(ipaddress, port);          // create tcp/ip socket.         var client = new socket(addressfamily.internetwork, sockettype.stream, protocoltype.tcp);          // connect remote endpoint.          //client.beginconnect(remoteep,             //new asynccallback(connectcallback), client);         var remoteep = new ipendpoint(ipaddress.parse("127.0.0.1"), port);         client.beginconnect(remoteep, connectcallback, client);         connectdone.waitone();          // set receive thread can receive, doesn't work intended         //var thread = new thread(() => readthread(client));         //thread.start();          // send test data remote device.         send(client, "this test<eof>");         senddone.waitone();          //test remove         // receive response remote device.         receive(client);         receivedone.waitone();          // write response console.         console.writeline("response received : {0}", _response);          // release socket.         //client.shutdown(socketshutdown.both);         //client.close();      }     catch (exception e)     {         console.writeline(e.tostring());     } }  // doesn't work expected private static void readthread(object ar) {     var client = (socket)ar;     while (true)     {         receive(client);         receivedone.waitone();          // write response console.         console.writeline("response received : {0}", _response);     } }  private static void connectcallback(iasyncresult ar) {     try     {         // retrieve socket state object.         var client = (socket)ar.asyncstate;          // complete connection.         client.endconnect(ar);          console.writeline("socket connected {0}", client.remoteendpoint);          // signal connection has been made.         connectdone.set();     }     catch (exception e)     {         console.writeline(e.tostring());     } }  private static void receive(socket client) {     try     {         // create state object.         var state = new stateobject {worksocket = client};          // begin receiving data remote device.         client.beginreceive(state.buffer, 0, stateobject.buffersize, 0, receivecallback, state);     }     catch (exception e)     {         console.writeline(e.tostring());     } }  private static void receivecallback(iasyncresult ar) {     try     {         // retrieve state object , client socket          // asynchronous state object.         var state = (stateobject)ar.asyncstate;         socket client = state.worksocket;          // read data remote device.         int bytesread = client.endreceive(ar);          if (bytesread > 0)         {             // there might more data, store data received far.             state.sb.append(encoding.ascii.getstring(state.buffer, 0, bytesread));              // rest of data.             client.beginreceive(state.buffer, 0, stateobject.buffersize, 0, receivecallback, state);         }         else         {             // data has arrived; put in response.             if (state.sb.length > 1)             {                 _response = state.sb.tostring();             }             // signal bytes have been received.             receivedone.set();         }     }     catch (exception e)     {         console.writeline(e.tostring());     } }  private static void send(socket client, string data) {     // convert string data byte data using ascii encoding.     var bytedata = encoding.ascii.getbytes(data);      // begin sending data remote device.     client.beginsend(bytedata, 0, bytedata.length, 0, sendcallback, client); }  private static void sendcallback(iasyncresult ar) {     try     {         // retrieve socket state object.         var client = (socket)ar.asyncstate;          // complete sending data remote device.         int bytessent = client.endsend(ar);         console.writeline("sent {0} bytes server.", bytessent);          // signal bytes have been sent.         senddone.set();     }     catch (exception e)     {         console.writeline(e.tostring());     } }  /* public static int main(string[] args) {     startclient();     return 0; } */ } 

previous system worked

server:

class program {      private static byte[] buffer = new byte[1024];     public static socket _serversocket = new socket(addressfamily.internetwork, sockettype.stream, protocoltype.tcp);     public static list<socket> clientsockets = new list<socket>();      static void main(string[] args)     {         console.title = "server, " + clientsockets.count + " clients connected";         setupserver();         console.readline();     }     public static void setupserver()     {         console.writeline("setting server...");         _serversocket.bind(new ipendpoint(ipaddress.any, 3030));         _serversocket.listen(10);         _serversocket.beginaccept(acceptcallback, null);         console.readline();// stops cmd closing     }      public static void acceptcallback(iasyncresult ar)     {         socket socket = _serversocket.endaccept(ar);         if (!clientsockets.contains(socket))             clientsockets.add(socket);         ipendpoint remoteipendpoint = socket.remoteendpoint ipendpoint;          console.writeline(remoteipendpoint.address);          console.writeline("client connected");         console.title = "server, " + clientsockets.count + " clients connected";         socket.beginreceive(buffer, 0, buffer.length, socketflags.none, recievecallback, socket);         _serversocket.beginaccept(acceptcallback, null);     }      private static void recievecallback(iasyncresult ar)     {         var socket = (socket)ar.asyncstate;         int received = socket.endreceive(ar);         var databuff = new byte[received];         array.copy(buffer, databuff, received);          string s = encoding.ascii.getstring(databuff);         console.writeline("text received: " + s);         string response = string.empty;          switch (s.tolower())         {             case "get time":                 response = datetime.now.tolongtimestring();                 break;             case "hello":                 response = "olleh";                 break;             case "update clients":                 response = "";                 senddata("ack", socket);                 doupdateclients();                 break;             default:                 response = "invavlid request";                 break;         }          senddata(response, socket);     }      private static void senddata(string data, socket socket)     {         byte[] data = encoding.ascii.getbytes(data);         socket.beginsend(data, 0, data.length, socketflags.none, sendcallback, socket);         socket.beginreceive(buffer, 0, buffer.length, socketflags.none, recievecallback, socket);     }      private static void doupdateclients()     {         // need send update message clients         var upd = new thread((updateclients));         upd.start();     }      private static void updateclients()     {         thread.sleep(5000);         foreach (var sock in clientsockets)         {             senddata("updateclients", sock);         }     }     private static void sendcallback(iasyncresult ar)     {         var socket = (socket)ar.asyncstate;         socket.endsend(ar);     }     // }  } 

client:

class program {      private static byte[] buffer = new byte[1024];     public static socket _clientsocket = new socket(addressfamily.internetwork, sockettype.stream, protocoltype.tcp);      static void main(string[] args)     {         console.title = "client ";         loopconnect();         //receiveloopstart();         //_clientsocket.listen(10);         sendloop();         console.readline();     }      private static void loopconnect()     {         while (!_clientsocket.connected)         {             try             {                 _clientsocket.connect(ipaddress.parse("127.0.0.1"), 3030);             }             catch (socketexception se)             {              }         }         console.writeline("connected");     }     private static void receiveloopstart()     {         //_clientsocket.bind(new ipendpoint(ipaddress.any, 3030));         //_clientsocket.listen(10);         _clientsocket.beginaccept(acceptcallback, null);          thread receivethread = new thread(receiveloop);         receivethread.start();     }      private static void receiveloop()     {         _clientsocket.beginreceive(buffer, 0, buffer.length, socketflags.none, recievecallback, _clientsocket);         _clientsocket.beginaccept(acceptcallback, null);     }      private static void recievecallback(iasyncresult ar)     {         int received = _clientsocket.endreceive(ar);         var databuff = new byte[received];         array.copy(buffer, databuff, received);          string s = encoding.ascii.getstring(databuff);         console.writeline("text received: " + s);         string response = string.empty;          switch (s.tolower())         {             case "get time":                 response = datetime.now.tolongtimestring();                 break;             case "hello":                 response = "olleh";                 break;             default:                 response = "invavlid request";                 break;         }      }     public static void acceptcallback(iasyncresult ar)     {         socket socket = _clientsocket.endaccept(ar);          console.writeline("client connected");         socket.beginreceive(buffer, 0, buffer.length, socketflags.none, recievecallback, socket);         _clientsocket.beginaccept(acceptcallback, null);     }        private static void sendloop()     {         while (true)         {             console.write("enter request: ");             string req = console.readline();              var buffer = encoding.ascii.getbytes(req);             _clientsocket.send(buffer);              var tempbuff = new byte[1024];             int rec = _clientsocket.receive(tempbuff);              var data = new byte[rec];             array.copy(tempbuff, data, rec);              console.writeline("received: " + encoding.ascii.getstring(data));         }     }   } } 

i don't have example sleeve here in c# need learn use select api.
need single thread this. use same thread process sockets in use @ point in time.
if nobody connected have listening socket. , use select api watch happens on socket. select blocking call when no timeout specified. if data available, means can call accept. result of accept know socket. use 2 sockets in select. again select block until 1 of sockets has data. perhaps listening socket again, socket after calling accept. use 3 sockets in select. suppose 1 of accept sockets have data available see using select api properly. , can use of sockets send on it, except of course listening socket not intended sending.

more info can found here : http://www.codeproject.com/articles/20066/a-scalable-client-server-using-select-socket-funct

it uses explained , gives more elaborate explanations too.


Comments

Popular posts from this blog

angularjs - ADAL JS Angular- WebAPI add a new role claim to the token -

php - CakePHP HttpSockets send array of paramms -

node.js - Using Node without global install -