Unity3d provides a socket for developers to use, syntax and consistency in. Net.
In general, for hand-travel clients, there are two threads, one is gles rendering and the other is the socket thread.
Article turn from (Http://blog.csdn.net/huutu)
Either the server or the client. Both the receiving and sending of packets are through the socket.
For example, if the client wants to log in, we create a new socket,connect to the account server. The account server has been waiting for the client to connect, and the client is ready to send the incoming packet after the connection is in.
Article turn from (Http://blog.csdn.net/huutu)
This article speaks only of the simple model of the server.
Sockets are encapsulated in. Net.
The socket is also divided into two types: blocking and asynchronous.
Obstruction, that is, you have to go to the back, you have to wait for me to carry out the completion.
Async, is to say you want to go back, see me take a detour.
Article turn from (Http://blog.csdn.net/huutu)
First introduce the basic usage of sockets:
1. New socket
2. Activate socket to wait for client connection status
3, asynchronous socket, be sure to return to the waiting state immediately after a client is linked in
private static int m_socketcount = 0; private static ManualResetEvent m_manualresetevent = new ManualResetEvent (false);
IPEndPoint: Is the integration type of IP address and port
Socket: Creates a socket based on IP address and port number
PROTOCOLTYPE.TCP: Specifies that the TCP protocol is used. (With regard to TCP and UDP, it is simply that TCP ensures that a packet must be sent successfully, regardless of UDP.) For more information please Baidu Google 360 search and so on)
BeginAccept: Start listening for client-side onboarding. Note that this is an asynchronous function. This function executes the code immediately after execution, and if there are no loops, then the program exits!
So here we use ManualResetEvent to wait for the result.
We can also single-thread to achieve this effect, the article will be pasted in the following two ways of code.
IPEndPoint IPEndPoint = new IPEndPoint (Ipaddress.parse ("172.16.30.167"), 1223); Socket ServerSocket = new socket (addressfamily.internetwork, SocketType.Stream, protocoltype.tcp); Try { serversocket.bind (ipendpoint); Serversocket.listen (a); Console.WriteLine ("Server Start"); while (true) { m_manualresetevent.reset ();//Put the thread in a non-terminating state, that is, waiting for the current thread to complete; Serversocket.beginaccept (New AsyncCallback (Accept), serversocket); M_manualresetevent.waitone (); Block the main thread, the role here is not to quit the program;} } catch (System.Exception ex) { Console.WriteLine ("Exception" + ex); }
Asynchronous socket mode, where each operation requires a callback function to be passed in. (or else if they do, then go down and execute ...)
For example, the above beginaccept passed in a callback function Accept, and with the parameter serversocket. This means that beginaccept will call accept and pass in ServerSocket after execution is complete.
Article turn from (Http://blog.csdn.net/huutu)
public static void Accept (IAsyncResult result) { m_manualresetevent.set ();//notifies the main thread to continue; Socket ServerSocket = (socket) result. asyncstate; Console.WriteLine ("Accept One Client" + (++m_socketcount)); After the client has been accept, stop accept; Socket Receiversocket = serversocket.endaccept (result); Start receive; StateObject state = new StateObject (); State.m_cursocket = Receiversocket; Receiversocket.beginreceive (state.m_buffer, 0, stateobject.m_buffersize, 0, New AsyncCallback (ReceiveCallBack), State); }
The accept is executed after the client has been linked in.
Note here:
Be sure to call the ManualResetEvent's set method to notify the main thread to continue execution, that is, let the socket continue to listen for the client's union.
Article turn from (Http://blog.csdn.net/huutu)
When the client is connected, it is time for the client to interact with the server's real data. Call Socket.beginreceive. This is also an asynchronous operation, and we're going to pass in a callback function.
public static void ReceiveCallback (IAsyncResult result) {String content = String.Empty; StateObject state = (stateobject) result. asyncstate; Socket receiversocket = State.m_cursocket; try {int byteread = receiversocket.endreceive (result); if (Byteread > 0) {//Get data length; Byte[] Datalengtharr=new byte[4]; Buffer.blockcopy (state.m_buffer, 0, Datalengtharr, 0, 4); int datalength = Bitconverter.toint32 (Datalengtharr, 0); Console.WriteLine ("Receive Data length =" + datalength. ToString ()); Get the data body; byte[] Dataarr = new Byte[byteread-4]; Buffer.blockcopy (State.m_buffer, 4, Dataarr, 0, byteRead-4); State.m_StringBuilder.Append (Encoding.ASCII.GetString (Dataarr, 0, byteRead-4)); Content = State.m_StringBuilder.ToString (); Determine the length of the data, whether received completely; if (! ( ByteRead-4 < Datalength) {Console.WriteLine ("Receive" + content. Length + "" + content); Send data to the client after receiving it completely; Send (Receiversocket, "Success from Server"); } else {//data is not received, continue to receive; Receiversocket.beginreceive (state.m_buffer, 0, stateobject.m_buffersize, 0, New AsyncCallback (ReceiveCallBack), State); }}} catch (Exception ex) {Console.WriteLine (ex). ToString ()); } }
Before the network game friends have doubts, in the receipt of data, how to know the end of the reception is complete?
In the above code, there is a special number 4.
This is a variable that we use to store the packet size.
Packet = data size (4 bytes) + Real Data
According to the above structure to build the packet, when the data received, we simply determine the received data size-4 is not equal to the size of the data.
All right. Here is the source code for the example:
(i) Collaboration using ManualResetEvent:
Using system;using system.net;using system.net.sockets;using System.IO; using system.text;using System.Threading; public class echoserver{private static int m_socketcount = 0; private static ManualResetEvent m_manualresetevent = new ManualResetEvent (false); Entry point of Main method. public static void Main () {IPEndPoint ipendpoint = new IPEndPoint (Ipaddress.parse ("172.16.30.167"), 1223); Socket ServerSocket = new socket (addressfamily.internetwork, SocketType.Stream, protocoltype.tcp); try {serversocket.bind (ipendpoint); Serversocket.listen (20); Console.WriteLine ("Server Start"); while (true) {m_manualresetevent.reset ();//Put the thread in a non-terminating state, that is, waiting for the current thread to complete; Serversocket.beginaccept (New AsyncCallback (Accept), serversocket); M_manualresetevent.waitone (); Block the main thread, the role here is not to quit the program; }} catch (System.Exception ex) { Console.WriteLine ("Exception" + ex); }} public static void Accept (IAsyncResult result) {m_manualresetevent.set ();//notify the main thread to continue; Socket ServerSocket = (socket) result. asyncstate; Console.WriteLine ("Accept One Client" + (++m_socketcount)); After the client has been accept, stop accept; Socket Receiversocket = serversocket.endaccept (result); Start receive; StateObject state = new StateObject (); State.m_cursocket = Receiversocket; Receiversocket.beginreceive (state.m_buffer, 0, stateobject.m_buffersize, 0, New AsyncCallback (ReceiveCallBack), State); public static void ReceiveCallback (IAsyncResult result) {String content = String.Empty; StateObject state = (stateobject) result. asyncstate; Socket receiversocket = State.m_cursocket; try {int byteread = receiversocket.endreceive (result); if (Byteread > 0) {//Get data length; Byte[] DataLengtharr=new Byte[4]; Buffer.blockcopy (state.m_buffer, 0, Datalengtharr, 0, 4); int datalength = Bitconverter.toint32 (Datalengtharr, 0); Console.WriteLine ("Receive Data length =" + datalength. ToString ()); Get the data body; byte[] Dataarr = new Byte[byteread-4]; Buffer.blockcopy (State.m_buffer, 4, Dataarr, 0, byteRead-4); State.m_StringBuilder.Append (Encoding.ASCII.GetString (Dataarr, 0, byteRead-4)); Content = State.m_StringBuilder.ToString (); Determine the length of the data, whether received completely; if (! ( ByteRead-4 < Datalength) {Console.WriteLine ("Receive" + content. Length + "" + content); Send data to the client after receiving it completely; Send (Receiversocket, "Success from Server"); } else {//data is not received, continue to receive; Receiversocket.beginreceive (state.m_Buffer, 0, stateobject.m_buffersize, 0, New AsyncCallback (ReceiveCallback), state); }}} catch (Exception ex) {Console.WriteLine (ex). ToString ()); }} public static void Send (Socket handler, String data) {byte[] bytedata = Encoding.ASCII.GetBytes (data ); try {handler. BeginSend (bytedata, 0, bytedata.length, 0, New AsyncCallback (Sendcallback), handler); } catch (Exception ex) {Console.WriteLine (ex. ToString ()); }} public static void Sendcallback (IAsyncResult result) {try {Socket handler = (Socket) result. asyncstate; int bytessend = handler. EndSend (result); Console.WriteLine ("Sent {0} bytes to client.", Bytessend); Handler. Shutdown (Socketshutdown.both); Handler. Close (); } catch (System.Exception ex) {Console.WriteLine (ex. ToStRing ()); }} public class StateObject {public Socket m_cursocket = null; public const int m_buffersize = 1024; Public byte[] M_buffer = new Byte[m_buffersize]; Public StringBuilder M_stringbuilder = new StringBuilder (); }}
article turn from (Http://blog.csdn.net/huutu)
(ii) Use of threads
Using system;using system.net;using system.net.sockets;using System.IO; using system.text;using System.Threading; public class echoserver{private static int m_socketcount = 0; private static ManualResetEvent m_manualresetevent = new ManualResetEvent (false); Entry point of Main method. public static void Main () {IPEndPoint ipendpoint = new IPEndPoint (Ipaddress.parse ("172.16.30.167"), 1223); Socket ServerSocket = new socket (addressfamily.internetwork, SocketType.Stream, protocoltype.tcp); try {serversocket.bind (ipendpoint); Serversocket.listen (20); Console.WriteLine ("Server Start"); while (true) {m_manualresetevent.reset ();//Put the thread in a non-terminating state, that is, waiting for the current thread to complete; Serversocket.beginaccept (New AsyncCallback (Accept), serversocket); M_manualresetevent.waitone (); Block the main thread, the role here is not to quit the program; }} catch (System.Exception ex) { Console.WriteLine ("Exception" + ex); }} public static void Accept (IAsyncResult result) {m_manualresetevent.set ();//notify the main thread to continue; Socket ServerSocket = (socket) result. asyncstate; Console.WriteLine ("Accept One Client" + (++m_socketcount)); After the client has been accept, stop accept; Socket Receiversocket = serversocket.endaccept (result); Start receive; StateObject state = new StateObject (); State.m_cursocket = Receiversocket; Receiversocket.beginreceive (state.m_buffer, 0, stateobject.m_buffersize, 0, New AsyncCallback (ReceiveCallBack), State); public static void ReceiveCallback (IAsyncResult result) {String content = String.Empty; StateObject state = (stateobject) result. asyncstate; Socket receiversocket = State.m_cursocket; try {int byteread = receiversocket.endreceive (result); if (Byteread > 0) {//Get data length; Byte[] DataLengtharr=new Byte[4]; Buffer.blockcopy (state.m_buffer, 0, Datalengtharr, 0, 4); int datalength = Bitconverter.toint32 (Datalengtharr, 0); Console.WriteLine ("Receive Data length =" + datalength. ToString ()); Get the data body; byte[] Dataarr = new Byte[byteread-4]; Buffer.blockcopy (State.m_buffer, 4, Dataarr, 0, byteRead-4); State.m_StringBuilder.Append (Encoding.ASCII.GetString (Dataarr, 0, byteRead-4)); Content = State.m_StringBuilder.ToString (); Determine the length of the data, whether received completely; if (! ( ByteRead-4 < Datalength) {Console.WriteLine ("Receive" + content. Length + "" + content); Send data to the client after receiving it completely; Send (Receiversocket, "Success from Server"); } else {//data is not received, continue to receive; Receiversocket.beginreceive (state.m_Buffer, 0, stateobject.m_buffersize, 0, New AsyncCallback (ReceiveCallback), state); }}} catch (Exception ex) {Console.WriteLine (ex). ToString ()); }} public static void Send (Socket handler, String data) {byte[] bytedata = Encoding.ASCII.GetBytes (data ); try {handler. BeginSend (bytedata, 0, bytedata.length, 0, New AsyncCallback (Sendcallback), handler); } catch (Exception ex) {Console.WriteLine (ex. ToString ()); }} public static void Sendcallback (IAsyncResult result) {try {Socket handler = (Socket) result. asyncstate; int bytessend = handler. EndSend (result); Console.WriteLine ("Sent {0} bytes to client.", Bytessend); Handler. Shutdown (Socketshutdown.both); Handler. Close (); } catch (System.Exception ex) {Console.WriteLine (ex. ToStRing ()); }} public class StateObject {public Socket m_cursocket = null; public const int m_buffersize = 1024; Public byte[] M_buffer = new Byte[m_buffersize]; Public StringBuilder M_stringbuilder = new StringBuilder (); }}
Unity3d game with C # Server asynchronous socket Interaction (i)