事件驅動的TCP協議Socket通信
介紹
常規的Socket通信案例一般都是在某個線程中建立連接,然后用一個while(true)循環判斷是或否有數據傳輸,但是這種方法有局限性。
1、收到消息在處理過程中無法接受新消息
2、線程容易堵塞
3、需要客戶端服務端雙發進行心跳響應
事件驅動的方式可以有效的提高Socket通信效率,讓在一端有操作的同時,可以觸發另一端的事件。
類似工具庫:Cowboy.Socket、FastSocket
使用方法
1、打開VS,在Nuget里搜索SuperSocket
2、安裝SuperSocket.Client和SuperSocket
3、服務端監聽端口以及注冊事件
AppServer appServer;
appServer = new AppServer();
if (!appServer.Setup(int.Parse(txt_port.Text)))
{
SetMessage("Failed to Setup");
return;
}
if (!appServer.Start())
{
SetMessage("Failed to Start");
return;
}
else
{
SetMessage("開啟監聽");
}
//SuperSocket自定義了三個事件 ,連接事件,接收事件,關閉事件
appServer.NewSessionConnected += appServer_NewSessionConnected;
appServer.NewRequestReceived += appServer_NewRequestReceived;
appServer.SessionClosed += appServer_SessionClosed;
4、服務端事件
void appServer_NewSessionConnected(AppSession session)
{
//有新連接的時候,添加記錄 session.LocalEndPoint屬性獲取當前session的ip和端口號
//AppSession 代表一個和客戶端的邏輯連接,基於連接的操作應該定於在該類之中。你可以用該類的實例發送數據到客戶端,接收客戶端發送的數據或者關閉連接。
//獲取遠程客戶端的ip端口號
ipAddress_Connect = session.RemoteEndPoint.ToString();
ComboboxHandle(ipAddress_Connect, OperateType.Add);
sessionList.Add(ipAddress_Connect, session);
SetMessage(ipAddress_Connect + "已連接!");
}
/// <summary>
/// 接收數據
/// </summary>
/// <param name="session"></param>
/// <param name="requestInfo"></param>
void appServer_NewRequestReceived(AppSession session, StringRequestInfo requestInfo)
{
//requestInfo.Key 是請求的命令行用空格分隔開的第一部分
//requestInfo.Parameters 是用空格分隔開的其余部分
//requestInfo.Body 是出了請求頭之外的所有內容
ipAddress_Receive = session.RemoteEndPoint.ToString();
SetMessage("收到" + ipAddress_Receive + "數據: "+requestInfo.Key +" "+ requestInfo.Body);
}
/// <summary>
/// 關閉連接
/// </summary>
/// <param name="session"></param>
/// <param name="value"></param>
void appServer_SessionClosed(AppSession session, SocketBase.CloseReason value)
{
ipAddress_Close = session.RemoteEndPoint.ToString();
ComboboxHandle(ipAddress_Close, OperateType.Remove);
sessionList.Remove(ipAddress_Close);
SetMessage(ipAddress_Close + "已關閉連接!");
}
5、客戶端建立連接以及注冊事件
SuperSocket.ClientEngine.AsyncTcpSession async=new AsyncTcpSession();
async.Connect(new IPEndPoint(IPAddress.Parse(ip), port));
async.Connected += client_Connected;
// 發生錯誤的處理
async.Error += client_Error;
// 收到服務器數據事件
async.DataReceived += client_DataReceived;
async.Closed += client_Closed;
6、客戶端事件
void client_Error(object sender, ErrorEventArgs e)
{
Console.WriteLine(e.Exception.Message);
}
void client_Connected(object sender, EventArgs e)
{
Console.WriteLine("連接成功");
}
void client_DataReceived(object sender, DataEventArgs e)
{
string msg = Encoding.Default.GetString(e.Data);
MessageBox.Show(msg.ToString());
Console.WriteLine(msg);
}
void client_Closed(object sender, EventArgs e)
{
Console.WriteLine("連接斷開");
}
7、客戶端/服務端發送消息
Client:
string message = "123";
byte[] data = Encoding.Default.GetBytes(message);
async.Send(data,0,data.Length);
8、其他
服務端接受消息必須要有回車加換行符:\r\n
源碼地址
碼雲地址:https://gitee.com/PErobin/Socket.git
SVN地址:svn://gitee.com/PErobin/Socket