同步Socket 与 异步 Socket

陈志
2023-12-01

同步Socket 与 异步 Socket:

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

2.异步就是不用等待;

同步Socket

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);
			}
           
		}
	}
}

}

异步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

}

服务器端

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);
}

}

客户端

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);
		}
	}
}

}

 类似资料: