美文网首页
C# socket在断开网线后不能重连

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

作者: GoodTekken | 来源:发表于2022-03-02 16:59 被阅读0次

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

    相关文章

      网友评论

          本文标题:C# socket在断开网线后不能重连

          本文链接:https://www.haomeiwen.com/subject/umnwlrtx.html