c# - Need help to solve some logic error about Asynchronous Server Socket -
this programme establishing connection between 1 server , multi client. process of handshaking client generate hash , send server.the server generate pair of public , private key , encrypt hash , send encrypt hash public key client.
my problem server did not respond info want, server respond signature(encrypted hash) public key instead.
my reputation not high plenty post image of result type out
socket connected {0}127.0.01:1100 sent {0} bytes server : 8 signature: ??.p1?z??7/)??#u?m?????b?=???,?w???u?n?&f? sent {0} bytes server : 2 publickey: ??.p1?z??7/)??#u?m?????b?=???,?w???u?n?&f?another problem don't know how prepare server hanging program, there infinite while loop @ server asynchronous class @ startlistening() method
there 2 different project 1 server , 1 client
the server side code
the asynchronous server socket code
using unityengine; using system.collections; using system; using system.net; using system.net.sockets; using system.text; using system.threading; using system.security.cryptography; // state object receiving info remote device. 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 info string. public stringbuilder sb = new stringbuilder (); } public class asynchronousserversocket : monobehaviour { // thread signal. public static manualresetevent alldone = new manualresetevent (false); public asynchronousserversocket () { } public socket listener; public server serverclass; public asciiencoding myascii = new asciiencoding (); public void startlistening () { // info buffer incoming data. byte[] bytes = new byte[1024]; // found local endpoint socket. // dns name of computer // running listener "host.contoso.com". iphostentry iphostinfo = dns.gethostentry ("127.0.0.1"); ipaddress ipaddress = iphostinfo.addresslist [0]; ipendpoint localendpoint = new ipendpoint (ipaddress, 11000); // create tcp/ip socket. listener = new socket (addressfamily.internetwork,sockettype.stream, protocoltype.tcp); // bind socket local endpoint , hear incoming connections. seek { listener.bind (localendpoint); listener.listen (1024); while (true) { // set event nonsignaled state. alldone.reset (); // start asynchronous socket hear connections. debug.log ("waiting connection..."); listener.beginaccept (new asynccallback (acceptcallback), listener); // wait until connection made before continuing. alldone.waitone (); } //startcoroutine("stupidunityhang"); } grab (exception e) { debug.log (e.tostring ()); } } public ienumerator stupidunityhang () { { // set event nonsignaled state. alldone.reset (); // start asynchronous socket hear connections. debug.log ("waiting connection..."); listener.beginaccept (new asynccallback (acceptcallback), listener); // wait until connection made before continuing. alldone.waitone (); yield homecoming new waitforseconds (1); } while(true); } public void acceptcallback (iasyncresult ar) { // signal main thread continue. alldone.set (); // socket handles client request. socket listener = (socket)ar.asyncstate; socket handler = listener.endaccept (ar); // create state object. stateobject state = new stateobject (); state.worksocket = handler; handler.beginreceive (state.buffer, 0, stateobject.buffersize, 0, new asynccallback (stageone), state); alldone.waitone (); handler.beginreceive (state.buffer, 0, stateobject.buffersize, 0, new asynccallback (stagetwo), state); //alldone.set(); } // sending client signature , public key public void stageone (iasyncresult ar) { string content = string.empty; string check = string.empty; stateobject state = (stateobject)ar.asyncstate; socket handler = state.worksocket; int bytesread = handler.endreceive (ar); if (bytesread > 0) { state.sb.append (encoding.ascii.getstring (state.buffer, 0, bytesread)); content = state.sb.tostring (); byte[] hashbyte = myascii.getbytes (content); serverclass.generatepublicprivatekey (); byte [] signature = serverclass.sendencrypthash (hashbyte); content = myascii.getstring (signature); send (handler, content); } } public void stagetwo (iasyncresult ar) { string content = string.empty; string check = string.empty; stateobject state = (stateobject)ar.asyncstate; socket handler = state.worksocket; int bytesread = handler.endreceive (ar); if (bytesread > 0) { //state.sb.append(encoding.ascii.getstring(state.buffer,0,bytesread)); //content = state.sb.tostring(); //if(content =="pk") //{ rsacryptoserviceprovider rsacsp = new rsacryptoserviceprovider (); rsaparameters publickey = serverclass.sendpublickey (); rsacsp.importparameters (publickey); content = rsacsp.toxmlstring (false); send (handler, content); //} } } private void send (socket handler, string data) { // convert string info byte info using ascii encoding. byte[] bytedata = encoding.ascii.getbytes (data); // begin sending info remote device. handler.beginsend (bytedata, 0, bytedata.length, 0, new asynccallback (sendcallback), handler); } private void sendcallback (iasyncresult ar) { seek { // retrieve socket state object. socket handler = (socket)ar.asyncstate; // finish sending info remote device. int bytessent = handler.endsend (ar); debug.log ("sent {0} bytes client." + bytessent); handler.shutdown (socketshutdown.both); handler.close (); } grab (exception e) { debug.log (e.tostring ()); } } }
the server process code
using unityengine; using system.collections; using system.collections.generic; using system.security.cryptography; using system.io; using system.text; using system; public class server : monobehaviour { public rsaparameters rsaprivatekey; public rsaparameters rsapublickey; public void generatepublicprivatekey () { rsacryptoserviceprovider rsacsp = new rsacryptoserviceprovider (); rsaprivatekey = rsacsp.exportparameters (true); rsapublickey = rsacsp.exportparameters (false); } public rsaparameters sendpublickey () { homecoming rsapublickey; } public byte[] hashandsign (byte[] encrypted) { rsacryptoserviceprovider rsacsp = new rsacryptoserviceprovider (); sha1managed hash = new sha1managed (); byte[] hasheddata; rsacsp.importparameters (rsaprivatekey); hasheddata = hash.computehash (encrypted); homecoming rsacsp.signhash (hasheddata, cryptoconfig.mapnametooid ("sha1")); } public byte[] sendencrypthash (byte[] tmp) { homecoming hashandsign (tmp); } public byte[] sendencryptaeshash (byte[]hash, byte[]key, byte[]iv) { rsacryptoserviceprovider rsacsp = new rsacryptoserviceprovider (); rsacsp.importparameters (rsaprivatekey); byte[] decryptedsessionkey = rsacsp.decrypt (key, false); byte[] decryptedsessioniv = rsacsp.decrypt (iv, false); homecoming encrypt_function (hash, decryptedsessionkey, decryptedsessioniv); } private static byte[] encrypt_function (byte[] plainbytes, byte[] key, byte[] iv) { rijndaelmanaged crypto = null; memorystream memstream = null; icryptotransform encryptor = null; cryptostream crypto_stream = null; seek { crypto = new rijndaelmanaged (); crypto.key = key; crypto.iv = iv; memstream = new memorystream (); encryptor = crypto.createencryptor (crypto.key, crypto.iv); crypto_stream = new cryptostream (memstream, encryptor, cryptostreammode.write); crypto_stream.write (plainbytes, 0, plainbytes.length); } { if (crypto != null) crypto.clear (); crypto_stream.close (); } homecoming memstream.toarray (); } }
server main program
using unityengine; using system.collections; public class serverprogram : monobehaviour { public asynchronousserversocket asynchronousserverclass; public void start () { asynchronousserverclass.startlistening (); } }
client side code
asynchronous client class
using unityengine; using system.collections; using system; using system.net; using system.net.sockets; using system.threading; using system.text; using system.security.cryptography; // state object receiving info remote device. 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 info string. public stringbuilder sb = new stringbuilder (); } public class asynchronousclientsocket : monobehaviour { // port number remote device. private const int port = 11000; // manualresetevent instances signal completion. private static manualresetevent connectdone = new manualresetevent (false); private static manualresetevent senddone = new manualresetevent (false); private static manualresetevent receivedone = new manualresetevent (false); // response remote device. private string response = string.empty; public client clientclass; public asciiencoding myascii = new asciiencoding (); public void startclient () { // connect remote device. seek { // found remote endpoint socket. // name of // remote device "host.contoso.com". iphostentry iphostinfo = dns.gethostentry ("127.0.0.1"); ipaddress ipaddress = iphostinfo.addresslist [0]; ipendpoint remoteep = new ipendpoint (ipaddress, port); // create tcp/ip socket. socket client = new socket (addressfamily.internetwork, sockettype.stream, protocoltype.tcp); // connect remote endpoint. client.beginconnect (remoteep, new asynccallback (connectcallback), client); connectdone.waitone (); byte[] hashbyte = clientclass.sendhash (); string hashstring = myascii.getstring (hashbyte); // send test info remote device. send (client, hashstring); senddone.waitone (); // receive response remote device. receive (client); receivedone.waitone (); // write response console. debug.log ("signature: " + response); byte[] signature = myascii.getbytes (response); send (client, "pk"); senddone.waitone (); receive (client); receivedone.waitone (); debug.log ("publickey: " + response); rsacryptoserviceprovider rsacsp = new rsacryptoserviceprovider (); rsacsp.fromxmlstring (response); rsaparameters publickey = rsacsp.exportparameters (false); if (clientclass.verifyhash (publickey, hashbyte, signature)) { debug.log ("success"); } else { debug.log ("problem"); } // release socket. client.shutdown (socketshutdown.both); client.close (); } grab (exception e) { console.writeline (e.tostring ()); } } private void connectcallback (iasyncresult ar) { seek { // retrieve socket state object. socket client = (socket)ar.asyncstate; // finish connection. client.endconnect (ar); debug.log ("socket connected {0}" + client.remoteendpoint.tostring ()); // signal connection has been made. connectdone.set (); } grab (exception e) { debug.log (e.tostring ()); } } private void receive (socket client) { seek { // create state object. stateobject state = new stateobject (); state.worksocket = client; // begin receiving info remote device. client.beginreceive (state.buffer, 0, stateobject.buffersize, 0, new asynccallback (receivecallback), state); } grab (exception e) { debug.log (e.tostring ()); } } private void receivecallback (iasyncresult ar) { seek { // retrieve state object , client socket // asynchronous state object. stateobject state = (stateobject)ar.asyncstate; socket client = state.worksocket; // read info remote device. int bytesread = client.endreceive (ar); if (bytesread > 0) { // there might more data, store info received far. state.sb.append (encoding.ascii.getstring (state.buffer, 0, bytesread)); // rest of data. client.beginreceive (state.buffer, 0, stateobject.buffersize, 0, new asynccallback (receivecallback), state); } else { // info has arrived; set in response. if (state.sb.length > 1) { response = state.sb.tostring (); } // signal bytes have been received. receivedone.set (); } } grab (exception e) { debug.log (e.tostring ()); } } private void send (socket client, string data) { // convert string info byte info using ascii encoding. byte[] bytedata = encoding.ascii.getbytes (data); // begin sending info remote device. client.beginsend (bytedata, 0, bytedata.length, 0, new asynccallback (sendcallback), client); } private void sendcallback (iasyncresult ar) { seek { // retrieve socket state object. socket client = (socket)ar.asyncstate; // finish sending info remote device. int bytessent = client.endsend (ar); debug.log ("sent {0} bytes server." + bytessent); // signal bytes have been sent. senddone.set (); } grab (exception e) { debug.log (e.tostring ()); } } }
client processing class method
using unityengine; using system.collections; using system.collections.generic; using system.security.cryptography; using system.io; using system.text; using system; public class client : monobehaviour { public string hash; public byte[] sessionkeybyte; public byte[] sessionivbyte; public byte[] sessionkey; public byte[] sessioniv; static readonly char[] availablecharacters = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '`', '~', '-', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '=', '+', '/', '{', '}', '[', ']', '|','\\', ':', ';', '"','\'', '<', '>', ',', '.', '?', '!' }; internal static string generateidentifier (int length) { char[] identifier = new char[length]; byte[] randomdata = new byte[length]; rngcryptoserviceprovider rng = new rngcryptoserviceprovider (); rng.getbytes (randomdata); (int idx = 0; idx < identifier.length; idx++) { int pos = randomdata [idx] % availablecharacters.length; identifier [idx] = availablecharacters [pos]; } homecoming new string (identifier); } public byte[] sendhash () { hash = generateidentifier (8); asciiencoding myascii = new asciiencoding (); homecoming myascii.getbytes (hash); } public bool verifyhash (rsaparameters rsaparams, byte[] signeddata, byte[] signature) { rsacryptoserviceprovider rsacsp = new rsacryptoserviceprovider (); sha1managed hash = new sha1managed (); byte[] hasheddata; rsacsp.importparameters (rsaparams); hasheddata = hash.computehash (signeddata); homecoming rsacsp.verifyhash (hasheddata, cryptoconfig.mapnametooid ("sha1"), signature); } public void encryptsessionkey (rsaparameters temp) { rijndaelmanaged crypto = new rijndaelmanaged (); rsacryptoserviceprovider rsacsp = new rsacryptoserviceprovider (); rsacsp.importparameters (temp); sessionkey = crypto.key; sessioniv = crypto.iv; sessionkeybyte = rsacsp.encrypt (sessionkey, false); sessionivbyte = rsacsp.encrypt (sessioniv, false); } public byte[] sendsessionkey () { homecoming sessionkeybyte; } public byte[] sendsessioniv () { homecoming sessionivbyte; } private static string decrypt_function ( byte[] cipher_text, byte[] key, byte[] iv) { rijndaelmanaged crypto = null; memorystream memstream = null; icryptotransform decryptor = null; cryptostream crypto_stream = null; streamreader stream_read = null; string plain_text; seek { crypto = new rijndaelmanaged (); crypto.key = key; crypto.iv = iv; memstream = new memorystream (cipher_text); decryptor = crypto.createdecryptor (crypto.key, crypto.iv); crypto_stream = new cryptostream (memstream, decryptor, cryptostreammode.read); stream_read = new streamreader (crypto_stream); plain_text = stream_read.readtoend (); } { if (crypto != null) crypto.clear (); memstream.flush (); memstream.close (); } homecoming plain_text; } public string decrypthash (byte[] temp) { homecoming decrypt_function (temp, sessionkey, sessioniv); } public bool verifysessionkey (string temp) { if (temp == hash) { homecoming true; } else { homecoming false; } } public void clearhash () { hash = ""; } }
client main program
using unityengine; using system.collections.generic; public class clientprogram : monobehaviour { public string log; public asynchronousclientsocket asynchronousclientclass; public void ongui () { guilayout.beginarea (new rect (screen.width / 2 - 250, screen.height / 2 - 250, 500, 500)); gui.textarea (new rect (0, 0, 500, 300), log); if (gui.button (new rect (200, 310, 100, 30), "connect")) { asynchronousclientclass.startclient (); } guilayout.endarea (); } }
need help format code, seek many time format code, maintain pop "your post appear contain code.... within code tab. align code left , work well...
i new in unity , new in networking , security programming stuff, hope can point me improve way of writing .
ouch ... head hurts ... seek simpler ...
http://ccoder.co.uk/files/sockets.zip
that should going :)
this subset of code much bigger project have (an mmo server scheme unity games). should finish time !!!
c# asynchronous network-programming unity3d client-server
No comments:
Post a Comment