1、方法介紹
BeginAccept(AsyncCallback callback, object state);
異步開始監聽客戶端連接。
- callback為一個委托,在成功接收客戶端連接時調用委托方法。
- 向委托方法中傳遞的參數
**EndAccept (IAsyncResult result);** 結束監聽客戶端連接,一般在委托中成功接收連接后使用。 1. **result**:它存儲此異步操作的狀態信息以及任何用戶定義數據。 返回。使用**result.AsyncState** 可以接收傳遞過來的參數。
**BeginReceive (byte[] buffer, int offset, int size, SocketFlags flag, AsyncCallback callback, object state);** 異步接收服務器發送來的數據 1. 存儲接收的數據 2. 從buffer哪開始存儲數據 3. 要接受最大的字節數 4. SocketFlags 值的按位組合 5. 接收成功后調用的委托方法 6. 要傳遞的參數
2、服務器端
namespace Tcp服務器端
{
class Program
{
/// <summary>
/// 接收客戶端發送數據數組
/// </summary>
static byte[] data = new byte[1024];
static void Main(string[] args)
{
StartServerAsync();
}
static void StartServerAsync()
{
Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
EndPoint point = new IPEndPoint(IPAddress.Parse("192.168.1.3"), 5555);
serverSocket.Bind(point);
serverSocket.Listen(100);
//異步監聽客戶端連接
serverSocket.BeginAccept(AcceptCallBack,serverSocket);
Console.ReadKey();
}
/// <summary>
/// 接收到客戶端連接時調用
/// </summary>
static void AcceptCallBack(IAsyncResult ar)
{
Console.WriteLine("一個客戶端連接了進來\n");
Socket serverSocket = null;
try
{
//接收傳遞過來的main中的serverSocket
serverSocket = ar.AsyncState as Socket;
//結束接收,返回接收到的clientSocket
Socket clientSocket = serverSocket.EndAccept(ar);
clientSocket.Send(Encoding.UTF8.GetBytes("你好呀。。。客戶端"));
//異步開始監聽客戶端傳遞數據
clientSocket.BeginReceive(data, 0, 1024, SocketFlags.None, ReceiveCallBack, clientSocket); //從頭開始存,最大數量,none,接收到客戶端后執行的回調函數,要傳遞的參數(會被傳遞給回調函數)
//繼續處理下一個客戶端的連接,相當於一個偽遞歸
serverSocket.BeginAccept(AcceptCallBack, serverSocket);
}
catch (Exception e)
{
Console.WriteLine(e);
if (serverSocket != null)
serverSocket.Close();
}
}
/// <summary>
/// 接收到客戶端發送的數據時調用
/// </summary>
static void ReceiveCallBack(IAsyncResult ar)
{
Socket clientSocket = null;
try
{
clientSocket = ar.AsyncState as Socket;
int count = clientSocket.EndReceive(ar);
//正常關閉的情況
if (count == 0)
{
Console.WriteLine("一個客戶端正常斷開了連接");
clientSocket.Close();
return;
}
Console.WriteLine("接收到數據:" + Encoding.UTF8.GetString(data, 0, count));
clientSocket.BeginReceive(data, 0, 1024, SocketFlags.None, ReceiveCallBack, clientSocket); //從頭開始存,最大數量,none,接收到客戶端后執行的回調函數,要傳遞的參數
}
catch (Exception e)
{
//非正常關閉的情況
Console.WriteLine(e);
if (clientSocket != null)
clientSocket.Close();
}
}
}
}
3、客戶端
namespace Tcp客戶端
{
class Program
{
static void Main(string[] args)
{
Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
EndPoint point = new IPEndPoint(IPAddress.Parse("192.168.1.3"), 5555);
clientSocket.Connect(point);
byte[] data = new byte[1024];
int length = clientSocket.Receive(data);
Console.WriteLine(Encoding.UTF8.GetString(data, 0, length));
//循環向服務器發送數據
while (true)
{
string s = Console.ReadLine();
//輸入c正常退出,直接按×異常退出
if (s == "c")
{
clientSocket.Close();
return;
}
clientSocket.Send(Encoding.UTF8.GetBytes(s));
}
Console.ReadKey();
}
}
}
4、效果
服務器可以接收多個客戶端連接
多個客戶端都可以向服務器發送數據