C# socket在断开网线后不能重连

2022-03-02  本文已影响0人  GoodTekken

进度:经过以下代码(服务端)的测试,在客户端关机或者服务端软件的关闭后重新打开,网络可以自动连接,但是如果插拔网线,就是出现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异常退出.png

根据一篇文章中提示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>
上一篇 下一篇

猜你喜欢

热点阅读