BeginAccept未调用包含EndAccept的AcceptCallback函数问题求助
异步Socket服务端BeginAccept未触发回调的问题解决
你的代码存在几个核心逻辑错误,导致BeginAccept的回调无法正常工作,甚至整个服务端逻辑完全走不通:
- 监听套接字的Connected属性判断错误:
ServerSocket是负责监听连接请求的套接字,它本身永远不会处于Connected状态,所以while (!connected)里的判断永远不会成立,这个循环会无限执行,反复调用BeginAccept,既浪费CPU资源,也会让后续逻辑完全没有执行机会。 - BeginAccept被重复调用:BeginAccept只需要调用一次就能启动连接监听,当有客户端发起连接时会自动触发回调,不需要放在循环里反复执行。如果需要接受多个客户端连接,应该在AcceptCallback回调结束后再次调用BeginAccept。
- 错误使用监听套接字收发数据:监听套接字仅用于接受连接请求,实际和客户端通信的是
EndAccept返回的Handler套接字,你后续用ServerSocket调用Receive和Send是完全错误的。
修正后的完整代码
using System; using System.Net; using System.Net.Sockets; using System.Text; public class Server { // 用于和客户端通信的套接字 private static Socket _clientSocket; public static void Main() { IPAddress serverAddress = IPAddress.Parse("127.0.0.1"); int serverPort = 1234; Socket listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); listenSocket.Bind(new IPEndPoint(serverAddress, serverPort)); listenSocket.Listen(5); Console.WriteLine("Server is listening for connections"); // 启动异步接受连接,仅需调用一次 listenSocket.BeginAccept(AcceptCallback, listenSocket); // 保持主线程运行,避免程序直接退出 Console.WriteLine("按任意键退出..."); Console.ReadKey(); // 清理资源 _clientSocket?.Shutdown(SocketShutdown.Both); _clientSocket?.Close(); listenSocket.Close(); } private static void AcceptCallback(IAsyncResult ar) { Socket listenSocket = (Socket)ar.AsyncState; // 完成连接接受,获取与客户端通信的套接字 _clientSocket = listenSocket.EndAccept(ar); Console.WriteLine("Client connected!"); // 如果需要接受多个客户端连接,在此处再次调用BeginAccept // listenSocket.BeginAccept(AcceptCallback, listenSocket); // 启动异步接收客户端消息 StartReceive(); } private static void StartReceive() { byte[] buffer = new byte[1024]; // 异步接收客户端数据 _clientSocket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, ReceiveCallback, buffer); } private static void ReceiveCallback(IAsyncResult ar) { byte[] buffer = (byte[])ar.AsyncState; try { int bytesRead = _clientSocket.EndReceive(ar); if (bytesRead <= 0) { Console.WriteLine("客户端断开连接"); _clientSocket.Close(); return; } string clientMessage = Encoding.ASCII.GetString(buffer, 0, bytesRead); Console.WriteLine("Recieved data from client: " + clientMessage); // 接收完成后继续监听下一条消息 StartReceive(); // 处理发送逻辑:读取控制台输入并发送给客户端 Console.Write("输入要发送的消息:"); string serverMessage = Console.ReadLine(); if (!string.IsNullOrEmpty(serverMessage)) { byte[] sendBuffer = Encoding.ASCII.GetBytes(serverMessage); _clientSocket.BeginSend(sendBuffer, 0, sendBuffer.Length, SocketFlags.None, SendCallback, null); } } catch (Exception ex) { Console.WriteLine("接收数据出错:" + ex.Message); _clientSocket.Close(); } } private static void SendCallback(IAsyncResult ar) { try { _clientSocket.EndSend(ar); Console.WriteLine("消息发送成功"); } catch (Exception ex) { Console.WriteLine("发送数据出错:" + ex.Message); _clientSocket.Close(); } } }
关键修改说明
- 拆分套接字职责:将监听套接字
listenSocket和通信套接字_clientSocket分离,前者负责监听连接,后者负责和客户端收发数据。 - 异步流程闭环:用
BeginReceive和BeginSend实现非阻塞的收发逻辑,接收完成后再次调用StartReceive以持续监听客户端消息。 - 主线程保持存活:用
Console.ReadKey()让主线程保持运行,避免服务端启动后直接退出。 - 资源清理:在程序退出时主动关闭套接字,释放系统资源。
内容的提问来源于stack exchange,提问作者Doblob83
相关产品推荐
相关产品推荐

