【问题标题】:C# TCP multiple client issue when two clients run on the same machine当两个客户端在同一台机器上运行时 C# TCP 多客户端问题
【发布时间】:2019-08-26 19:50:59
【问题描述】:

我是 StackOverflow 的新手,我花了很多时间为我的问题寻找解决方案,但找不到任何解决方案。 所以,我想测试一个非常简单的 C# 服务器/多客户端应用程序。 它适用于具有不同 IP 地址的客户端。当我使用相同的 wi-fi 启动两个客户端时,服务器 socket.EndReceive 行上出现以下套接字异常:

“现有连接被远程主机强行关闭”

这是我的服务器代码:

class Program {

        private static Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        private static byte[] bufferPubblico = new byte[4096];

        static void Main(string[] args) {
            Console.WriteLine("Setting up server...");
            server.Bind(new IPEndPoint(IPAddress.Any, *port*));
            server.Listen(1);
            server.BeginAccept(new AsyncCallback(AcceptCallback), null);

            Console.ReadKey();
        }

        private static void AcceptCallback(IAsyncResult AR) {
            Socket socket = server.EndAccept(AR);
            Console.WriteLine("A new client connected");
            socket.BeginReceive(bufferPubblico, 0, bufferPubblico.Length, SocketFlags.None, new AsyncCallback(ReceiveCallBack), socket);
            server.BeginAccept(new AsyncCallback(AcceptCallback), null);
        }

        private static void ReceiveCallBack(IAsyncResult AR) {
            Socket socket = (Socket)AR.AsyncState;
            int received = socket.EndReceive(AR);
            byte[] dataBuf = new byte[received];
            Array.Copy(bufferPubblico, dataBuf, received);

            string text = Encoding.ASCII.GetString(dataBuf);
            Console.WriteLine("Text Received: " + text);

            socket.BeginReceive(bufferPubblico, 0, bufferPubblico.Length, SocketFlags.None, new AsyncCallback(ReceiveCallBack), socket);
        }
    }

这是我的客户端代码:

class Program
{
    private static Socket socket;
    private static byte[] bufferPubblico = new byte[4096];

    static void Main(string[] args) {
        string ip = Console.ReadLine();
        IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Parse(ip), *port*);
        socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        socket.Connect(localEndPoint);
        socket.BeginReceive(bufferPubblico, 0, bufferPubblico.Length, SocketFlags.None, new AsyncCallback(ReceiveCallBack), socket);

        while (true) {
            string messaggio = Console.ReadLine();
            byte[] data = Encoding.ASCII.GetBytes(messaggio);
            socket.Send(data);
        }
    }

    static void ReceiveCallBack(IAsyncResult AR) {
        Socket socket = (Socket)AR.AsyncState;
        int received = socket.EndReceive(AR);
        byte[] dataBuf = new byte[received];
        Array.Copy(bufferPubblico, dataBuf, received);

        string messaggio = Encoding.ASCII.GetString(dataBuf);
        Console.WriteLine("Text Received: " + messaggio);

        socket.BeginReceive(bufferPubblico, 0, bufferPubblico.Length, SocketFlags.None, new AsyncCallback(ReceiveCallBack), socket);
    }
}

所以,我的问题是,为什么当我连接两个共享相同 IP 的客户端时,会出现上述异常?

附:产生异常的两个客户端具有相同的服务器 IP,即它们在同一台计算机上启动。

帖子编辑: 我解决了添加

的问题

Socket.Close()

在结束应用程序之前关闭服务器和客户端之间的连接。 我以为不是那么重要,但是tcp连接必须关闭,否则会出现一些异常。

【问题讨论】:

  • 您发布的代码在我的电脑上运行良好。您确实有一个错误:您的服务器代码与每个连接共享bufferPubblico 字段。只要两个客户端不同时发送数据,这不会是问题,但如果他们这样做会导致问题。您应该确保为每个客户端分配一个唯一的缓冲区。如果您在遇到问题时需要帮助,请改进问题,使其包含一个很好的 minimal reproducible example 以可靠地重现问题。
  • 你真的需要这样轮询套接字吗?你能检查一下套接字是否可用,如果不可用,请尝试另一个端口?
  • @terribletp:OP 发布的代码中没有轮询。
  • @PeterDuniho 感谢您的评论。在我的完整项目中,服务器代码中有一个用户类,其中包含所有信息和每个用户的 byte[] 数据缓冲区,但异常仍然存在。
  • 网络代码不好玩吗?我会打开一个端点供客户端注册,然后从某种池中为它们分配一个连接。

标签: c# sockets tcp


【解决方案1】:

MSDN 有关于如何创建异步套接字服务器 here 的优秀指南。

学习本教程肯定会帮助您深入学习套接字编程(它是可复制/粘贴的代码)。

Socket API 需要注意的一点是,OnReceive 中可能不会收到所有数据,因此需要您检查字符串终止符,MSDN 使用了将 <EOF> 附加到您发送的每个字符串的结尾。

好好阅读一下article,看看它是否能解决您的问题。

【讨论】:

  • 感谢您的回答。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-07-15
  • 1970-01-01
  • 1970-01-01
  • 2020-06-11
  • 2012-10-07
  • 1970-01-01
  • 2018-02-14
相关资源
最近更新 更多