c# - Sockets receive hangs -
i trying download, search page of bing, , ask using sockets, have decided use sockets, instead of webclient.
the socket.receive(); hangs after few loops in case of bing, yahoo, google works ask. google loop receive 4 - 5 times, freeze on call.
i not able figure out why?
public string get(string url) { uri requesteduri = new uri(url); string fulladdress = requesteduri.host; iphostentry entry = dns.gethostentry(fulladdress); stringbuilder sb = new stringbuilder(); try { using (socket socket = new socket(addressfamily.internetwork, sockettype.stream, protocoltype.ip)) { socket.connect(entry.addresslist[0], 80); networkstream ns = new networkstream(socket); string part_request = string.empty; string build_request = string.empty; if (jar.count != 0) { part_request = "get {0} http/1.1\r\nhost: {1} \r\nuser-agent: mozilla/5.0 (windows; u; windows nt 5.1; en-us; rv:1.9.2.13) gecko/20101203 firefox/3.6.13\r\naccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\naccept-language: en-us,en;q=0.5\r\naccept-charset: iso-8859-1,utf-8;q=0.7,*;q=0.7\r\ncookie: {2}\r\nconnection: keep-alive\r\n\r\n"; build_request = string.format(part_request, requesteduri.pathandquery, requesteduri.host, getcookies(requesteduri)); } else { part_request = "get {0} http/1.1\r\nhost: {1} \r\nuser-agent: mozilla/5.0 (windows; u; windows nt 5.1; en-us; rv:1.9.2.13) gecko/20101203 firefox/3.6.13\r\naccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\naccept-language: en-us,en;q=0.5\r\naccept-charset: iso-8859-1,utf-8;q=0.7,*;q=0.7\r\nconnection: keep-alive\r\n\r\n"; build_request = string.format(part_request, requesteduri.pathandquery, requesteduri.host); } byte[] data = encoding.utf8.getbytes(build_request); socket.send(data, data.length, 0); byte[] bytesreceived = new byte[102400]; int bytes = 0; { bytes = socket.receive(bytesreceived, bytesreceived.length, 0); sb.append(encoding.ascii.getstring(bytesreceived, 0, bytes)); } while (bytes > 0); list<string> cookieheaders = new list<string>(); foreach (string header in sb.tostring().split("\n\r".tochararray(), stringsplitoptions.removeemptyentries)) { if (header.startswith("set-cookie")) { cookieheaders.add(header.replace("set-cookie: ", "")); } } this.addcookies(cookieheaders, requesteduri); socket.close(); } } catch (exception ex) { string errormessage = ex.message; } return sb.tostring(); } cookiecontainer jar = new cookiecontainer(); public string getcookies(uri _uri) { stringbuilder sb = new stringbuilder(); cookiecollection collection = jar.getcookies(_uri); if (collection.count != 0) { foreach (cookie item in collection) { sb.append(item.name + "=" + item.value + ";"); } } return sb.tostring(); }
its because you've reached end of content , yet still requesting more ...
do { bytes = socket.receive(bytesreceived, bytesreceived.length, 0); sb.append(encoding.ascii.getstring(bytesreceived, 0, bytes)); } while (bytes > 0);
this assumes long last request returned more 0 bytes theres more available, when in actual fact when network stream reaches end chances you'll fill of buffer on last loop. (e.g. bytes > 0 nothing more get) ... server closes connection.
try instead ...
do { bytes = socket.receive(bytesreceived, bytesreceived.length, 0); sb.append(encoding.ascii.getstring(bytesreceived, 0, bytes)); } while (bytes == bytesreceived.length);
some servers (ask 1 of them) abviously dont auto close connection expect hense reason dont fail.
:::edit:::
my test sample:
load visual studio, create new console app paste following in generated program class (in place of existing code):
using system; using system.collections.generic; using system.linq; using system.text; using system.net; using system.net.sockets; namespace consoleapplication1 { class program { static void main(string[] args) { string test = get("http://www.google.co.uk/search?q=test&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:en-gb:official&client=firefox-a"); console.read(); } public static string get(string url) { uri requesteduri = new uri(url); string fulladdress = requesteduri.host; iphostentry entry = dns.gethostentry(fulladdress); stringbuilder sb = new stringbuilder(); try { using (socket socket = new socket(addressfamily.internetwork, sockettype.stream, protocoltype.ip)) { socket.connect(entry.addresslist[0], 80); networkstream ns = new networkstream(socket); string part_request = string.empty; string build_request = string.empty; if (jar.count != 0) { part_request = "get {0} http/1.1\r\nhost: {1} \r\nuser-agent: mozilla/5.0 (windows; u; windows nt 5.1; en-us; rv:1.9.2.13) gecko/20101203 firefox/3.6.13\r\naccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\naccept-language: en-us,en;q=0.5\r\naccept-charset: iso-8859-1,utf-8;q=0.7,*;q=0.7\r\ncookie: {2}\r\nconnection: keep-alive\r\n\r\n"; build_request = string.format(part_request, requesteduri.pathandquery, requesteduri.host, getcookies(requesteduri)); } else { part_request = "get {0} http/1.1\r\nhost: {1} \r\nuser-agent: mozilla/5.0 (windows; u; windows nt 5.1; en-us; rv:1.9.2.13) gecko/20101203 firefox/3.6.13\r\naccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\naccept-language: en-us,en;q=0.5\r\naccept-charset: iso-8859-1,utf-8;q=0.7,*;q=0.7\r\nconnection: keep-alive\r\n\r\n"; build_request = string.format(part_request, requesteduri.pathandquery, requesteduri.host); } byte[] data = encoding.utf8.getbytes(build_request); socket.send(data, data.length, 0); byte[] bytesreceived = new byte[4096]; int bytes = 0; string currentbatch = ""; { bytes = socket.receive(bytesreceived); currentbatch = encoding.ascii.getstring(bytesreceived, 0, bytes); console.write(currentbatch); sb.append(currentbatch); } while (bytes == bytesreceived.length); list<string> cookieheaders = new list<string>(); foreach (string header in sb.tostring().split("\n\r".tochararray(), stringsplitoptions.removeemptyentries)) { if (header.startswith("set-cookie")) { cookieheaders.add(header.replace("set-cookie: ", "")); } } //this.addcookies(cookieheaders, requesteduri); socket.close(); } } catch (exception ex) { string errormessage = ex.message; } return sb.tostring(); } static cookiecontainer jar = new cookiecontainer(); public static string getcookies(uri _uri) { stringbuilder sb = new stringbuilder(); cookiecollection collection = jar.getcookies(_uri); if (collection.count != 0) { foreach (cookie item in collection) { sb.append(item.name + "=" + item.value + ";"); } } return sb.tostring(); } } }
i reduced buffer ensure filled more once ... seems ok end post comes typical works on pc garantee :)
Comments
Post a Comment