gpt4 book ai didi

c# - C# 中的远程主机强制关闭现有连接

转载 作者:行者123 更新时间:2023-12-03 12:08:54 25 4
gpt4 key购买 nike

我有基于 C# 的 Windows 服务,它使用 TCP 端口通过 Web 连接到多个客户端。服务器具有静态 IP,可帮助客户端定位服务器。我已经在这里发布了代码。

TcpListener tcp = new TcpListener(ipAddr, portNo);

tcp.Start();

listening = true;

while (listening)
{
Socket mySocket = null;

// Blocks until a client has connected to the server
try
{
mySocket = tcp.AcceptSocket();
Thread.Sleep(500);

byte[] bReceive = new byte[1024 * 1024 * 2];
int i = mySocket.Receive(bReceive);
byte[] databyte = new byte[i];

for (int j = 0; j < i; j++)
{
databyte[j] = bReceive[j];
}

Analysis(databyte, mySocket);
}
catch (Exception exc)
{
logger.Error(exc);
}
}

listening = false;
tcp.Stop();
有时我会遇到这两个错误之一,即关闭连接并且所有客户端都断开连接:
  • 远程主机在System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags).
  • 已建立的连接被主机中的软件中止System.Net.Sockets.Socket.Send(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)

  • 这些错误不是周期性的,而是会导致所有客户端在出现时断开连接。该服务连接到大约 300 个客户端。
    编辑 1:
    根据@Sean H 的建议,我修改了代码以异步读取数据。以下是代码:
    Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

    private static Logger logger = LogManager.GetCurrentClassLogger();

    //constructor
    public Server()
    {
    listener.Bind(new IPEndPoint(IPAddress.Parse("192.168.1.5"), 9000));
    listener.Listen(300);
    listener.BeginAccept(new AsyncCallback(OnConnectRequest), listener);
    //Console.Write("Server Running...\r\n");
    }

    public void OnConnectRequest(IAsyncResult ar)
    {
    Socket listener = (Socket)ar.AsyncState;
    Socket accepted = listener.EndAccept(ar);
    listener.BeginAccept(new AsyncCallback(OnConnectRequest), listener);
    NewConnection(accepted);
    }

    //send a string message over a TCP socket
    public void sendMSG(Byte[] bSendData, ref Socket mySocket)
    {
    //some code which sends data according to my protocol
    int numBytes = 0;

    try
    {
    if (mySocket.Connected)
    {
    if ((numBytes = mySocket.Send(bSendData, bSendData.Length, 0)) == -1)
    {
    logger.Error("Socket Error: Cannot Send Packet (Custom Error by me)");
    }
    else
    {
    }
    }
    else
    {
    logger.Error("Link Failed - Socket closed (Custom Error by me)");
    }
    }
    catch (Exception exc)
    {
    logger.Error(exc);
    }
    }

    public void receiveMSG(ref Socket mySocket)
    {
    byte[] bReceive = new byte[1024 * 1024 * 2];
    int i = mySocket.Receive(bReceive);
    byte[] databyte = new byte[i];

    for (int j = 0; j < i; j++)
    {
    databyte[j] = bReceive[j];
    }

    Analysis(databyte, mySocket);
    }


    //function called whenever a NEW CLIENT is connected
    public void NewConnection(Socket sockClient)
    {
    //Console.WriteLine("user {0} has joined", sockClient.RemoteEndPoint);
    //byte[] msg = new byte[20];
    receiveMSG(ref sockClient);
    //sockClient.Receive(msg);
    }
    这在测试环境中效果很好。
    我还没有将它部署在生产环境中,原因是服务器如何知道它收到的数据是否已完成,或者还有一部分字符串仍需从客户端传输到服务器。在将 Windows 服务部署到生产环境之前,我无法知道它的实际行为,因为我在测试环境中有 4 个客户端,而在生产环境中有 300 个客户端。
    但是@Sean H 的建议变得很棒,因为现在服务器不会被阻塞,直到处理来自客户端的请求。它正在同时收听多个客户。
    我对这种 TCP/IP 编程比较陌生,我的问题可能看起来很愚蠢......

    最佳答案

    我想我看到了你的问题。当您的 Analysis(byte, Socket) 方法正在运行时,您的服务器无法接受更多连接。一旦您接受来自客户端的套接字,您将不再监听该端口,直到您完成工作并再次调用 .AcceptSocket() 方法。

    相反,您应该将工作启动到异步方法,并在绑定(bind)当前客户端连接后再次开始监听。这是您想要做的一个很好的例子。

    https://docs.microsoft.com/en-us/dotnet/framework/network-programming/asynchronous-server-socket-example

    关于c# - C# 中的远程主机强制关闭现有连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46910267/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com