【问题标题】:Client not receiving message in time (TcpClient)客户端没有及时收到消息(TcpClient)
【发布时间】:2015-07-08 13:18:57
【问题描述】:

我有两个应用程序通过Tcp相互“对话”,问题是当我发送一些东西时,应用程序没有同时收到它,只有当他第二次请求时,然后'他'收到它重复。例如:

客户端请求连接(收入字符串:00200001 0050);

服务器接受连接(确认)(输出字符串:00570002);

客户端没有收到确认,但是当他再次请求连接时,它会收到一个输出字符串:00570002 00570002(重复)。

这发生在任何连接到我的应用程序中。

            private int listenerPort = 4545;
            private TcpListener listener;
            private TcpClient socket;

            public Communicator()
            {
                try
                {
                    this.listener = new TcpListener(IPAddress.Parse("127.0.0.1"), listenerPort);
                    listenerPort++;
                    listener.Start();
                    this.connectToPendingRequest();
                }
                catch (Exception ex)
                {
                    listener.Stop();
                    throw new Exception(ex.Message);
                }
            }

            /// <summary>
            /// Try to connect to any pending requests
            /// </summary>
            public void connectToPendingRequest()
            {
                try
                {
                    if (socket == null || !socket.Connected)
                        if (listener.Pending())
                        {
                            this.socket = Listener.AcceptTcpClient();
                            this.socket.NoDelay = true;
                        }
                }
                catch (InvalidOperationException) { throw new Exception("Listener was not started!"); }
                catch (Exception ex) { throw new Exception("Error has ocurred when connecting to device: " + ex.Message); }
            }

            /// <summary>
            /// Send messages to Device
            /// </summary>
            public void sendMessages(string stringMessage)
            {
                if (socket.Connected)
                {
                    try
                    {
                        byte[] outStream = Encoding.ASCII.GetBytes(stringMessage);
                        socket.GetStream().Write(outStream, 0, outStream.Length);
                        socket.GetStream().Flush();
                    }
                    catch (Exception ex)
                    {
                        throw new Exception("Message could not be sent.\nError: " + ex.Message);
                    }

                }
                else { throw new Exception("No device connected"); }

            }

        /// <summary>
        /// Get Message From socket
        /// </summary>
        /// <returns></returns>
        public String getMessageFromSocket()
        {
            try
            {
                byte[] inStream = new byte[10025];

                socket.GetStream().Read(inStream, 0, (int)socket.ReceiveBufferSize);
                return System.Text.Encoding.ASCII.GetString(inStream);
            }
            catch (Exception ex)
            {
                throw new Exception("Message could not be read.\nError: " + ex.Message);
            }
        }

我是不是忘记了什么?它有没有办法确保消息已经到达? (猜想 tcp 应该这样做,但是......)

Ps:我在接收消息时没有问题。

提前致谢!

【问题讨论】:

  • 你不是framing your messages,如果你正在使用套接字并且你没有对Read返回的int做任何事情你的程序有错误
  • 我敢打赌,这源于您忽略了 Read 的返回值 - 鉴于您的场景描述,我的猜测是第一次调用 Read 返回接收到的数据的正确大小,而第二次调用返回零(“连接关闭”) - 但由于您忽略返回值,因此您将两者解释为“打印出缓冲区中的所有数据”。但是很难判断您是否没有在客户端服务器中发布所有相关代码。有太多东西无法确定。
  • 问题是当我调用方法Write()两次时,客户端只收到一条消息,我正常接收客户端消息(感谢返回值的建议)ps:客户端应用程序不是我的

标签: c# sockets tcpclient


【解决方案1】:
  1. 不需要listenerPort++;。多个客户端可以连接到同一个端口上的同一个监听器
  2. 这里看不到客户端代码或者它与服务器代码纠缠在一起
  3. socket.GetStream().Flush() 不需要。
  4. .Pending() 是非阻塞的,因此您可能会错过连接时刻
  5. 查看TcpListenerTcpClient 代码示例

【讨论】:

  • 另外,OP 有一个10025 缓冲区并要求ReceiveBufferSize 的数据量,这势必会导致异常或缓冲区溢出。 10025 大小的缓冲区似乎是糟糕的网络教程的绝佳指标...
【解决方案2】:

下面是一个使用 Read() 的返回值的简单示例:

    /// <summary>
    /// Get Message From socket
    /// </summary>
    /// <returns></returns>
    public String getMessageFromSocket()
    {
        try
        {
            byte[] inStream = new byte[10025];

            int bytesRead = socket.GetStream().Read(inStream, 0, inStream.Length);
            return System.Text.Encoding.ASCII.GetString(inStream, 0, bytesRead);
        }
        catch (Exception ex)
        {
            throw new Exception("Message could not be read.\nError: " + ex.Message);
        }
    }

不过,不要忽视 Scott Chamberlain 给您的重要建议。这对于确定何时收到完整的“消息”这一更大的问题根本没有帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-22
    • 2021-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多