非同步Socket寫聊天程式
Socket類提供的方法成員中包含一組專門用來進行非同步操作的Socket方法。這些方法以成對出現:BeginConnect 與 EndConnect 提供非同步聯機功能、BeginAccept 與 EndAccept 提供非同步接受請求、 BeginReceive與 EndReceive 非同步接收資料、BeginSend與EndSend 非同步傳送資料。
其實這些方法和同步相當類似,最大的差異在於AsyncCallback類派生物件,上述的非同步方法接受一個AsyncCallback物件,封裝回撥方法,並在Socket網路操作完成之後,返回IAsyncResult介面物件。此物件被當作引數。傳入回撥的方法,回撥的方法呼叫結束相關非同步方法,並且傳入IAsyncResult,取得相關的非同步操作資訊。
public interface IAsyncResult
public delegate void AsyncCallback (IAsyncResult ar)
ar 為非同步操作的結果,獲取非同步操作的返回值。
服務端程式碼示例
private static ManualResetEvent allDone = new ManualResetEvent(false); //執行緒訊號
public static void StartListening(Socket listener, IPEndPoint localEndPoint)
{
listener.Bind(localEndPoint);
listener.Listen(100);
while (true)
{
allDone.Reset(); //將事件狀態設定為非終止狀態,導致執行緒阻止
//開啟一個非同步Socket來監聽客戶端連線請求
//並建立回撥,以便在有客戶請求連線後激發AcceptCallback()過程
listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
showMsg("正在等待一個新連線接入...");
allDone.WaitOne(); //等待連線
}
}
//請求回撥過程(當有一個新客戶端請求連線時發生)
private static void AcceptCallback(IAsyncResult ar)
{
//從IAsyncResult介面中得到客戶端請求的Socket物件
Socket listener = (Socket)ar.AsyncState;
Socket handler = listener.EndAccept(ar);
//StateObject:一個使用者定義物件,其中包含接收操作的相關資訊。當操作完成時,
//此物件會被傳遞給EndReceive 委託。
StateObject state = new StateObject();
state.workSocket = handler;
//建立一個接收資訊的回撥,以便在收到資訊時激發ReceiveCallback()過程
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReceiveCallback), state);
}
//接收資訊回撥過程(當接收到客戶端資訊時發生)
private static void ReceiveCallback(IAsyncResult ar)
{
String content = String.Empty;
StateObject state = (StateObject)ar.AsyncState;
Socket handler = state.workSocket;
//從客戶端的Socket中讀取資訊
int bytesRead = handler.EndReceive(ar);
//在此加入資訊處理並顯示接收到的資訊
//建立一個新的接收資訊的回撥,以便在收到新資訊時繼續本過程
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReceiveCallback), state);
}
輔助物件
public class StateObject
{
public Socket workSocket = null;
public const int BufferSize = 256;
public byte[] buffer = new byte[BufferSize];
public string strMsg = string.Empty;
}
客戶端程式
private static ManualResetEvent connectDone = new ManualResetEvent(false);
private static ManualResetEvent sendDone = new ManualResetEvent(false);
private static ManualResetEvent receiveDone = new ManualResetEvent(false);
private static String response = String.Empty; //遠端裝置接收到的資訊
public static void StartClient(Socket client, IPEndPoint remoteEP)
{
client.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), client);
connectDone.WaitOne();
}
private static void ConnectCallback(IAsyncResult ar)
{
Socket client = (Socket)ar.AsyncState;
client.EndConnect(ar);
System.Diagnostics.Debug.WriteLine("連線成功:" + client.RemoteEndPoint.ToString());
connectDone.Set();
}
private static void Receive(Socket client)
{
//建立stateObject.
StateObject state = new StateObject();
state.workSocket = client;
//開始從遠端裝置接收資訊
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReceiveCallback), state);
}
private static void ReceiveCallback(IAsyncResult ar)
{
StateObject state = (StateObject)ar.AsyncState;
Socket client = state.workSocket;
client = state.workSocket;
//讀取資訊
int bytesRead = client.EndReceive(ar);
//資訊處理
}
public static void Send(Socket client, String data)
{
byte[] byteData = Encoding.UTF8.GetBytes(data);
//向遠端裝置傳送資訊
client.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), client);
}
private static void SendCallback(IAsyncResult ar)
{
Socket client = (Socket)ar.AsyncState;
//所有資訊已被髮送
int bytesSent = client.EndSend(ar);
}
上面的示例只說明瞭非同步聊天程式的原理,沒有對可能發生的異常進行處理和其它輔助方法。
相關文章
- Socket程式設計中的同步、非同步、阻塞和非阻塞(轉)程式設計非同步
- Python使用Socket寫一個簡單聊天程式Python
- socket阻塞與非阻塞,同步與非同步、I/O模型非同步模型
- java Socket Udp聊天JavaUDP
- Python Socket 程式設計:聊天室示例程式Python程式設計
- 簡單的聊天程式,主要用到的是Socket
- socket實現聊天功能(二)
- PHP 編寫基本的 Socket 程式PHP
- 影片聊天原始碼,同步、非同步示例程式碼分析原始碼非同步
- react+react-router+redux+Node.js+socket.io寫一個聊天webappReactReduxNode.jsWebAPP
- 初用SOCKET做聊天室程式後所想到的…… (轉)
- node.js 用socket實現聊天Node.js
- UNIX Domain Socket實現簡易聊天AI
- 同步非同步,阻塞非阻塞非同步
- 非同步、同步、阻塞、非阻塞非同步
- 同步、非同步、阻塞、非阻塞非同步
- android socket聊天室——也不僅僅是聊天室Android
- linux非阻塞式socket程式設計之select()用法Linux程式設計
- Socket.IO打造基礎聊天室
- 同步非同步 與 阻塞非阻塞非同步
- 理解阻塞、非阻塞、同步、非同步非同步
- 同步、非同步,阻塞、非阻塞理解非同步
- 同步、非同步、阻塞與非阻塞非同步
- 同步、非同步、阻塞和非阻塞非同步
- 程式執行緒、同步非同步、阻塞非阻塞、併發並行執行緒非同步並行
- 聊聊執行緒與程式 & 阻塞與非阻塞 & 同步與非同步執行緒非同步
- 併發-0-同步/非同步/阻塞/非阻塞/程式/執行緒非同步執行緒
- Generator:同步程式碼書寫非同步情懷非同步
- Netty實現的一個非同步Socket程式碼Netty非同步
- [譯] 非同步程式設計:阻塞與非阻塞非同步程式設計
- 基於Java的Socket類Tcp網路程式設計實現實時聊天互動程式(一):QQ聊天介面的搭建JavaTCP程式設計
- [轉]阻塞/非阻塞與同步/非同步非同步
- 同步與非同步 阻塞與非阻塞非同步
- [python3.3]Python非同步Socket程式設計【TCP】Python非同步程式設計TCP
- 非同步 SOCKET 程式設計 - 傳送和接收資料 (轉)非同步程式設計
- java同步非阻塞IOJava
- 非同步和非阻塞非同步
- 同步、非同步、阻塞、非阻塞的區別非同步