一种C# TCP异步编程中遇到的问题
发表于:2026-10-31 作者:千家信息网编辑
千家信息网最后更新 2026年10月31日,最近在维护公司的一个socket服务端工具,该工具主要是提供两个socket server服务,对两端连接的程序进行数据的透明转发。程序运行期间,遇到一个问题,程序的一端是GPRS设备,众所周知,GP
千家信息网最后更新 2026年10月31日一种C# TCP异步编程中遇到的问题
最近在维护公司的一个socket服务端工具,该工具主要是提供两个socket server服务,对两端连接的程序进行数据的透明转发。
程序运行期间,遇到一个问题,程序的一端是GPRS设备,众所周知,GPRS设备的网络连接十分的不问题,由此会产生不少的"奇怪"问题。
实际过程中,程序运行几个小时后,无线端的socket server断开就再也无法打开。找了很久都没发现。
通过wireshark抓取通信报文,一般是在TCP的三次握手时出的问题。
常规的TCP三次握手,由TCP的标识可简单看作:SYN-SYN ACK-ACK,实际遇到问题时,标识为:SYN-RST ACK。
可以明显看出,服务端发出了重置的标识,用来积极的拒绝了客户端的连接。
程序的server部分代码,采用的常规的TCP异步编程方式,一下是MSDN代码
// This server waits for a connection and then uses asynchronous operations to // accept the connection with initial data sent from the client. // Establish the local endpoint for the socket. IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName()); IPAddress ipAddress = ipHostInfo.AddressList[0]; IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000); // Create a TCP/IP socket. Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp ); // Bind the socket to the local endpoint, and listen for incoming connections. listener.Bind(localEndPoint); listener.Listen(100); while (true) { // Set the event to nonsignaled state. allDone.Reset(); // Start an asynchronous socket to listen for connections and receive data from the client. Console.WriteLine("Waiting for a connection..."); // Accept the connection and receive the first 10 bytes of data. // BeginAccept() creates the accepted socket. int receivedDataSize = 10; listener.BeginAccept(null, receivedDataSize, new AsyncCallback(AcceptReceiveDataCallback), listener); // Wait until a connection is made and processed before continuing. allDone.WaitOne(); } } public static void AcceptReceiveDataCallback(IAsyncResult ar) { // Get the socket that handles the client request. Socket listener = (Socket) ar.AsyncState; // End the operation and display the received data on the console. byte[] Buffer; int bytesTransferred; Socket handler = listener.EndAccept(out Buffer, out bytesTransferred, ar); //再次投递接收,实现一直接收socket的操作 listener.BeginAccept(null, receivedDataSize, new AsyncCallback(AcceptReceiveDataCallback), listener); }经过问题的定位,可以判断可能是程序的异步接收回调中出了问题,但实际添加调试信息后发现,在程序出现端口无法打开后,再进行回调函数操作,并无信息打出。
TCP异步编程,一般是成对的出现beginXXX...endXXX,再通过回调函数进行具体处理。
如下为accept的回调函数,代码中使用了try..catch来捕获异常,实际问题可能就出在这里,代码如下:
public static void AcceptReceiveDataCallback(IAsyncResult ar) { // Get the socket that handles the client request. Socket listener = (Socket) ar.AsyncState; // End the operation and display the received data on the console. byte[] Buffer; int bytesTransferred; try{ Socket handler = listener.EndAccept(out Buffer, out bytesTransferred, ar); } catch(异常1 e){ ... return; } catch(异常2 e){ ... return; } //再次投递接收,实现一直接收socket的操作 listener.BeginAccept(null, receivedDataSize, new AsyncCallback(AcceptReceiveDataCallback), listener); }程序在实际出现端口不能打开之前曾经进入过"异常1"/"异常2",判断很可能是程序进行了return,而无法再次投递接收操作。
此时所有的端口打开操作,都会进入socket.listen(backlog)的队列中,当accpet队列中的内容无法通过完整begin..end操作取出,队列满后socket的底层协议栈则会拒绝新的socket连入。
程序
问题
实际
代码
再次
函数
标识
端口
队列
服务
编程
信息
工具
常规
端的
设备
运行
明显
众所周知
一端
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
广东猪兼强互联网科技有限公司
互联网科技公司华为
今日互联网科技
互联网络科技有限公司
互联网金融科技创新
北京禾田雨橡互联网科技
赫美联合互联网科技
互联网科技大会
互联网汽车科技小镇
互联网科技与管理
互联网科技的全部知识
玉溪新华互联网科技好不好
互联网科技如何创业
锡山区互联网智能科技产品供应
易租星互联网科技有限公司
数字互联网科技有限公司
河南商务圈互联网科技有限公司
上海互联网科技园景观
利用互联网等科技手段
互联网 科技节活动 微视频大赛
互联网金融监管科技数据
北京互联网络科技有限公司
奔汉互联网科技
猫创互联网科技
互联网科技产业特征
华夏恒生科技与互联网科技
互联网科技的全部知识
本届互联网大会上的黑科技
信承诺互联网科技有限公司
北京互联网科技类企业分布