【Unity】Socket 同步与异步

荆钱明
2023-12-01

同步Socket 与 异步 Socket:

1.同步就是阻塞的,比如 接受数据 如果没有回应 就一直等待。

2.异步就是不用等待;

同步Socket

<span style="font-size:24px;">using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;

//多线程
namespace MySocket
{

	class Program
	{
		//用于连接
		public static Socket connSocket;
		//用于请求
		public static Socket ComdSocket;

		public static byte[] buf = new byte[1024];


		static void Main (string[] args)
		{
          
			//开启一个新的线程当客户端
			Thread client = new Thread (InitClient);
			client.Start ();//开启
			InitServer ();

			Console.Read ();
		}


		public static void InitServer ()
		{
			//操作都放到try和catch中,以捕捉异常
			connSocket = new Socket (AddressFhamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
			//实例化一个终端
			IPEndPoint endPoint = new IPEndPoint (IPAddress.Parse ("127.0.0.1"), 3535);
			//占用一个房间
			connSocket.Bind (endPoint);
			//用于监听,可以接受10个人
			connSocket.Listen (10);
			//接受客户端对象,            重点:阻塞方法(block)
			ComdSocket = connSocket.Accept ();
			Console.WriteLine ("有客户端连接了,终端为" + ComdSocket.RemoteEndPoint);
			while (true) {
				//接受数据,阻塞方法(block)
				int len = ComdSocket.Receive (buf);
				string msg = Encoding.UTF8.GetString (buf, 0, len);
				Console.WriteLine ("收到新的消息:" + msg);
			}
           

		}


		public static void InitClient ()
		{
			//
			Thread.Sleep (3000);//休眠1000毫秒,保证服务器开启之后才能连接
			connSocket = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
			//实例化一个终端
			IPEndPoint endPoint = new IPEndPoint (IPAddress.Parse ("127.0.0.1"), 3535);
			//连接服务器
			connSocket.Connect (endPoint);
			Console.WriteLine (connSocket.Connected);
			if (connSocket.Connected) {
				while (true) {
					//客户端发送数据给服务器
					Console.WriteLine ("client input:");
					string msg = Console.ReadLine ();
					//讲一个字符串转换成byte[]

					buf = Encoding.UTF8.GetBytes (msg);
					//发送数据
					connSocket.Send (buf);
				}
               
			}
		}
	}
}</span>


异步Socket

using UnityEngine;
using System.Collections;

//关于网络
using System.Net;

//关于套接字
using System.Net.Sockets;

//关于文本
using System.Text;

//声明一个委托
public delegate void ldyReceiveCallBack (string content);

public class LdySocket
{
	#region 服务器端

	//声明一个服务器端的套接字
	Socket serverSocket;
	//声明一个委托对象
	ldyReceiveCallBack serverCallBake;
	//生成一个比特缓存
	byte[] serverBuffer = new byte[1024];
	//初始化服务器
	public void InitServer (ldyReceiveCallBack rcb)
	{
		//传入委托对象
		serverCallBake = rcb;
		//初始化服务器端的套接字
		serverSocket = new Socket (AddressFamily.InterNetwork/*IPV4*/, SocketType.Stream/*双向读写流(服务端可以发给客户 客户也可以发服务)*/,
			ProtocolType.Tcp/*TCP协议*/);
		//实例一个网络端点  传入地址和端口
		IPEndPoint serverEP = new IPEndPoint (IPAddress.Any, 23456);
		//绑定网络端点
		serverSocket.Bind (serverEP);
		//设置最大监听数量
		serverSocket.Listen (10);
		//异步接受客户端的连接(CallBack)
		serverSocket.BeginAccept (new System.AsyncCallback (ServerAccept), serverSocket);
		//发送一个消息 表示服务器已经创建
		serverCallBake ("Server Has Init");

	}
	//服务器接受
	void ServerAccept (System.IAsyncResult ar)
	{
		//接受结果状态
		serverSocket = ar.AsyncState  as Socket;
		//接收结果
		Socket workingSocket = serverSocket.EndAccept (ar);

		workingSocket.BeginReceive (serverBuffer/*消息缓存*/, 
			0/*接受消息的偏移量 就是从第几个开始*/, 
			this.serverBuffer.Length/*设置接受字节数*/,
			SocketFlags.None/*Socket标志位*/, 
			new System.AsyncCallback (ServerReceive)/*接受回调*/, 
			workingSocket/*最后的状态*/);

		//继续接受客户端的请求
		workingSocket.BeginAccept (new System.AsyncCallback (ServerAccept), workingSocket);

	}

	void ServerReceive (System.IAsyncResult ar)
	{
		//获取正在工作的Socket对象(用来接受数据的 )
		Socket workingSocket = ar.AsyncState as Socket;
		//接受到得数据字节 
		int byteCount = 0;
		//接收到的数据字符串
		string content = "";
		try {
			byteCount = workingSocket.EndReceive (ar);

		} catch (SocketException ex) {
			//如果接受失败 返回详细异常
			serverCallBake (ex.ToString ());
		}
		if (byteCount > 0) {
			//转换byte数组为字符串(支持中文)
			content = UTF8Encoding.UTF8.GetString (serverBuffer);
		}
		//发送接收到的消息
		serverCallBake (content);
		//继续接受消息
		workingSocket.BeginReceive (serverBuffer/*消息缓存*/, 
			0/*接受消息的偏移量 就是从第几个开始*/, 
			this.serverBuffer.Length/*设置接受字节数*/,
			SocketFlags.None/*Socket标志位*/, 
			new System.AsyncCallback (ServerReceive)/*接受回调*/, 
			workingSocket/*最后的状态*/);
	}



	#endregion

	#region

	//声明客户端的套接字
	Socket clientSocket;
	//声明客户端的委托对象
	ldyReceiveCallBack clientReceiveCallBack;
	//声明客户端的缓存1KB
	byte[] clientBuffer = new byte[1024];
	//1.ip地址 2.端口3.委托对象
	public void InitClient (string ip, int port, ldyReceiveCallBack rcb)
	{
		//接受委托对象
		clientReceiveCallBack = rcb;
		//实例客户端的Socket 参数(IPV4 ,双向读写流,TCP协议)
		clientSocket = new Socket (AddressFamily.InterNetwork,
			SocketType.Stream, ProtocolType.Tcp);
		//实例化一个客户端的网络端点        IPAddress.Parse (ip):将IP地址字符串转换为Ip地址实例
		IPEndPoint clientEP = new IPEndPoint (IPAddress.Parse (ip), port);
		//连接服务器
		clientSocket.Connect (clientEP);
		//第一个是缓存  第二个 是从第几个开始接受 第三个 接受多少个字节  第四个 需不需要特殊的服务 第五个回调函数 第六个当前对象
		clientSocket.BeginReceive (clientBuffer, 0, this.clientBuffer.Length, SocketFlags.None,
			new System.AsyncCallback (clientReceive), this.clientSocket);
	}

	void clientReceive (System.IAsyncResult ar)
	{
		//获取一个客户端正在接受数据的对象
		Socket workingSocket = ar.AsyncState as Socket;
		int byteCount = 0;
		string content = "";
		try {
			//结束接受数据 完成储存
			byteCount = workingSocket.EndReceive (ar);

		} catch (SocketException ex) {
			//如果接受消息失败
			clientReceiveCallBack (ex.ToString ());
		}
		if (byteCount > 0) {
			//转换已经接受到得Byte数据为字符串
			content = UTF8Encoding.UTF8.GetString (clientBuffer);
		}
		//发送数据
		clientReceiveCallBack (content);
		//接受下一波数据
		clientSocket.BeginReceive (clientBuffer, 0, this.clientBuffer.Length, SocketFlags.None,
			new System.AsyncCallback (clientReceive), this.clientSocket);
		
	}

	public void ClientSendMessage (string msg)
	{
		if (msg != "") {
			//将要发送的字符串消息转换成BYTE数组
			clientBuffer = UTF8Encoding.UTF8.GetBytes (msg);
		}
		clientSocket.BeginSend (clientBuffer, 0, this.clientBuffer.Length, SocketFlags.None,
			new System.AsyncCallback (SendMsg),
			this.clientSocket);
	}

	void SendMsg (System.IAsyncResult ar)
	{
		Socket workingSocket = ar.AsyncState as Socket;
		workingSocket.EndSend (ar);
	}

	#endregion
}


服务器端

<span style="font-size:24px;">using UnityEngine;
using System.Collections;

public class ServerSocketDemo : MonoBehaviour
{
	private LdySocket ldysocket;
	string serverContent;


	void Awake ()
	{
		ldysocket = new LdySocket ();
		//执行初始化服务器方法,传入委托函数
		ldysocket.InitServer (ShowMsg);
	}

	void ShowMsg (string msg)
	{
		serverContent = msg;
	}

	void OnGUI ()
	{
		GUILayout.Label (serverContent);
	}
}
</span>
客户端

<span style="font-size:24px;">using UnityEngine;
using System.Collections;

public class ClientSocketDemo : MonoBehaviour
{

	private LdySocket ldysocket;
	private string clientContent;
	private string needSendText = "";

	void Awake ()
	{
		ldysocket = new LdySocket ();
		ldysocket.InitClient ("127.0.0.1", 23456, (string msg) => {
			clientContent = msg;
		});
	}

	void OnGUI ()
	{
		needSendText = GUILayout.TextField (needSendText);
		if (GUILayout.Button ("点击发送消息")) {
			if (needSendText != "") {
				ldysocket.ClientSendMessage (needSendText);
			}
		}
	}
}</span>


 类似资料: