multithreading - C# Socket.receive continuously receives 0 bytes and does not block in the loop -
i trying write simplest multithreaded tcp server in c#, receives data multiple clients.
every time new client connected, socket connection established , socket passed argument new class function, after while loop runs , receives data till client connected.
the problem here "socket.receive" not blocking , receives 0 bytes of data. loop runs continuously, without blocking @ socket.receive ("clientsocket.receive(bb)" in code.).
i using chrome browser client testing. if use other client, behavior of tcp server remains same.
the client sends data once server continuously receives 0 bytes , while loop keeps on running.
i pasting server output reference.
please in blocking server @ socket.receive wait next client transmission. strange thing if 0 bytes received, exception not called.
please help.
using system; using system.collections.generic; using system.linq; using system.text; using system.net; using system.net.sockets; using system.threading; threading; using system.timers; using system.security; using system.security.permissions; namespace server { static class constants { public const int port = 8080; public const int buffer_size = 512; } class program { static public string localipaddress() { iphostentry host; string localip = ""; host = dns.gethostentry(dns.gethostname()); foreach (ipaddress ip in host.addresslist) { if (ip.addressfamily == addressfamily.internetwork) { localip = ip.tostring(); break; } } return localip; //return ip; } static void main(string[] args) { //ipendpoint ipobj = new ipendpoint(ipaddress.parse("server ip goes here"), 20487); //20487 port. can change according wish system.net.ipaddress ip = ipaddress.any; int port = constants.port; tcplistener listnerobj = new tcplistener(ip, port); listnerobj.start(); string client_addr; string[] client_addr_split; string ip_string = localipaddress(); console.writeline("server started on {0}:{1}", ip_string, port); while (true) { console.writeline("================================"); console.writeline("** waiting client **"); socket clientsocket = listnerobj.acceptsocket(); // waiting client connect client_addr = clientsocket.remoteendpoint.tostring(); client_addr_split = client_addr.split(':'); client_addr = client_addr_split[0]; console.writeline("client connected {0}", client_addr); parameterizedthreadstart thread = delegate { new communication().docommunicate(clientsocket, client_addr); }; thread th = new thread(thread); th.start(); // start thread here } } class communication { public int bytereceived; public byte[] bb; public void docommunicate(socket clientsocket, string client_addr) { clientsocket.blocking = true; bb = new byte[constants.buffer_size]; //console.writeline("***** entered docommunicate *****"); while (clientsocket.connected) { //console.writeline("entered while"); try { //console.writeline("entered try"); console.writeline("waiting recieve data ip : client_addr"); //int receiveddatalength = client.receive(receivedbytes, 0, receivedbytes.length, socketflags.none); bytereceived = clientsocket.receive(bb, 0, bb.length, socketflags.none); //bytereceived = clientsocket.receive(bb); } catch (socketexception e) { console.writeline("error: socket exception.\n{0}\n{1}.", e.message, e.errorcode); break; } catch (argumentnullexception e) { console.writeline("error : argument null exception.\n{0}", e.message); break; } catch (objectdisposedexception e) { console.writeline("error : socket disposed exception caught.\n{0}", e.message); break; } catch (securityexception e) { console.writeline("error: security exception.\n{0}", e.message); break; } //clientsocketglobal.send(encoding.default.getbytes("hello client"), socketflags.none); console.writelinewriteline("received byte count : {0}, ip : {1}", bytereceived, client_addr); // whatever want data recieved. parsing , storing etc. console.writeline(encoding.utf8.getstring(bb)); } //console.writeline("while loop exited"); console.writeline("socked , class object disposed"); clientsocket.close(); clientsocket.dispose(); gc.collect(); } } } }
output of server :
server started on 10.0.0.2:8080 ================================ ** waiting client ** client connected 10.0.0.2 ================================ ** waiting client ** client connected 10.0.0.2 ================================ ** waiting client ** waiting recieve data ip : 10.0.0.2 waiting recieve data ip : 10.0.0.2 received byte count : 386, ip : 10.0.0.2 /helloworld http/1.1 host: 10.0.0.2:8080 connection: keep-alive cache-control: max-age=0 accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 user-agent: mozilla/5.0 (windows nt 6.0; wow64) applewebkit/537.36 (khtml, gecko) chrome/30.0.1599.69 safari/537.36 accept-encoding: gzip,deflate,sdch accept-language: en-gb,en-us;q=0.8,en;q=0.6 waiting recieve data ip : 10.0.0.2 received byte count : 0, ip : 10.0.0.2 received byte count : 0, ip : 10.0.0.2 waiting recieve data ip : 10.0.0.2 waiting recieve data ip : 10.0.0.2 received byte count : 0, ip : 10.0.0.2 received byte count : 0, ip : 10.0.0.2 waiting recieve data ip : 10.0.0.2 waiting recieve data ip : 10.0.0.2 received byte count : 0, ip : 10.0.0.2 received byte count : 0, ip : 10.0.0.2 waiting recieve data ip : 10.0.0.2 waiting recieve data ip : 10.0.0.2 received byte count : 0, ip : 10.0.0.2 received byte count : 0, ip : 10.0.0.2 waiting recieve data ip : 10.0.0.2 waiting recieve data ip : 10.0.0.2 received byte count : 0, ip : 10.0.0.2 received byte count : 0, ip : 10.0.0.2 waiting recieve data ip : 10.0.0.2 waiting recieve data ip : 10.0.0.2 received byte count : 0, ip : 10.0.0.2 received byte count : 0, ip : 10.0.0.2 waiting recieve data ip : 10.0.0.2 waiting recieve data ip : 10.0.0.2 received byte count : 0, ip : 10.0.0.2 received byte count : 0, ip : 10.0.0.2 waiting recieve data ip : 10.0.0.2 waiting recieve data ip : 10.0.0.2 received byte count : 0, ip : 10.0.0.2 received byte count : 0, ip : 10.0.0.2
if received 0 bytes, means sender has closed send socket. in socket
, send , receive channels separate; expect happening send (their receive) still open , available, hence clientsocket.connected
returning true (you can still send them reply), but: closed send (your receive) sent payload (this common, indicate end of batch). basically, need detect 0-byte receive, , treat end: no more data ever incoming once have had non-positive reply receive. write response need write (they can still listening, though never speak again), , shutdown socket.
as side note: in http/1.1 connection: keep-alive
, can keep socket open ready send next request - looks in case, didn't. closed socket after issuing request. fine. serve response , close socket completely. no more requests incoming.
Comments
Post a Comment