C# socket在断开网线后不能重连
进度:经过以下代码(服务端)的测试,在客户端关机或者服务端软件的关闭后重新打开,网络可以自动连接,但是如果插拔网线,就是出现10053的网络错误,以及客户端反馈的[TCP Retransmission]重连报文,但此时的服务端并不能进行重连。(问题正在分析中......(2022年2月22日))
(偶尔成功了一次:服务器端回复:TCP acked unseen segment)
https://www.youtube.com/watch?v=IkJ7bYyAlXI
(10053事件:An Established Connection was Aborted by the Software in Your Host Machine)
根据一篇文章中提示socket会在网线断开的时候,存在Bugs:
http://dam.mellis.org/2004/08/net_socket_bugs_gotchas/
另外:
下面这篇文章提示window系统和linux系统会有区别:
https://bbs.csdn.net/topics/390753685
windows查看端口状态:netstat -aon|findstr 5678
windows 查看进程:tasklist | findstr 23140(pid)
linux查看端口状态:netstat -apn | grep 5678
linux查看进程: ps -e | ps -u | ps aux
linux杀死进程: kill -9 pid (pid为进程ID)
TCP Wireshark网络抓包分析,参考文章:https://www.i4k.xyz/article/hguisu/46273261()
---------------华丽的分割线-------------------------
linux测试流程:
(1)(Linux)client的网线拔出后,重新插入(Linux)server,可以使用客户端原来端口继续通信。(client和server的网络端口始终保持在ESTABLISHED状态)
(2)(Linux)client的网线拔出后,重新插入另外一台(Linux)server,最长几分钟后便重新建立连接,但此时(客户端已发现服务端网卡发生改变或者服务端没有客户端的端口),客户端使用了新的端口与服务端建立连接。
(2)(Linux)client的网线拔出后,退出(Linux)server的程序,重新打开。网线再次插入同一台(Linux)server,(服务器通知客户端没有对应的端口),使得客户端使用了新的端口与服务端建立连接。
测试代码
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace TestTCP_Reconnect
{
class Program
{
static void Main(string[] args)
{
//IPAddress ip = IPAddress.Parse("192.168.100.2");
//TcpListener server = new TcpListener(ip, 5678);
Configuration con = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
string ip_string = con.AppSettings.Settings["IP"].Value;
int port_int = Convert.ToInt32(con.AppSettings.Settings["Port"].Value);
IPAddress ip = IPAddress.Parse(ip_string);
TcpListener server = new TcpListener(ip, port_int);
server.Start();
Thread thread = new Thread(() =>
{
while (true)
{
string id = Guid.NewGuid().ToString();
// 异步接受传入的连接尝试,并创建新的 System.Net.Sockets.Socket 来处理远程主机通信。
AsyncCallback asynccallback = new AsyncCallback(GetShow);
IAsyncResult result = server.BeginAcceptSocket(asynccallback, id);
Socket socket = server.EndAcceptSocket(result);
result.AsyncWaitHandle.Close();
//发送消息
socket.Send(Encoding.UTF8.GetBytes(id));
//接收该Socket发来的数据
Thread read_data = new Thread((obj) =>
{
Socket _s = obj as Socket;
if (_s != null)
{
byte[] bytes = new byte[1024];
int i;
try
{
do
{
i = _s.Receive(bytes);
if (i > 0)
Console.WriteLine(id + ">>> " + Encoding.UTF8.GetString(bytes, 0, i));
} while (i > 0);
}
catch (Exception ex)
{
if( ex == null)
{
;
}
else
{
Console.WriteLine("退出:【" + id + "】");
_s.Close();
}
}
}
});
read_data.Start(socket);
}
});
thread.Start();
Console.WriteLine("----------------------------------------------");
Console.WriteLine("服务端开启服务");
Console.WriteLine("----------------------------------------------");
Console.WriteLine();
Console.Read();
}
static void GetShow(IAsyncResult resulr)
{
string id = resulr.AsyncState as string;
Console.WriteLine("进入:【" + id + "】");
}
}
}
配置文件:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<appSettings>
<add key ="IP" value="127.0.0.1"/>
<add key ="Port" value="5678"/>
</appSettings>
</configuration>