【问题标题】:C# - TcpClient just receive the first packetC# - TcpClient 只接收第一个数据包
【发布时间】:2017-05-10 10:48:29
【问题描述】:

我正在开发一个 c# 程序,只是为了了解有关 TcpClient 的一些知识。所以,这个程序从另一个程序接收到一个消息,并返回一个 OK 数据包给它,确认建立的连接。

在第一次请求时,它工作得很好,发回 OK 数据包没有任何问题。但在第二次请求时,它根本不回复。看起来它从未收到来自客户端的数据包。我可以使用数据包嗅探器看到数据包是从客户端发送的,但我的服务器没有任何动作。

它实际上是在控制台上打印所有请求,所以我可以查看是否有东西“进入”了读取流。如果我关闭服务器或客户端,然后重新打开以建立新连接,我会再次收到第一个数据包,但不是第二个。

我一直在寻找解决方案,至少一个星期。许多功能根本不适合我,我不希望应用程序断开连接并重新连接很多次。

我的服务器代码:

static void Main(string[] args)
{
    int InternalLoop = 0;
    bool Finished = false;
    TcpListener serverSocket = new TcpListener(System.Net.IPAddress.Any, 10000);
    int requestCount = 0;
    TcpClient clientSocket = default(TcpClient);
    serverSocket.Start();
    while (true)
    {
        bool LoopReceive = true;
        bool LoopSend = false;

        Console.WriteLine(" :::: SERVER STARTED OK");
        clientSocket = serverSocket.AcceptTcpClient();
        Console.WriteLine(" :::: CONNECTED TO CLIENT");
        requestCount = 0;
        NetworkStream networkStream = clientSocket.GetStream();

        string Packettosend = "";

        while (LoopReceive == true)
        {
            try
            {
                //Gets the Client Packet
                requestCount = requestCount + 1;
                byte[] bytesFrom = new byte[128];
                networkStream.Read(bytesFrom, 0, bytesFrom.Length);
                string dataFromClient = System.Text.Encoding.ASCII.GetString(bytesFrom);

                Packettosend = "ALIVE";
                Console.WriteLine(" ::: SENDING ALIVE PACKET");
                LoopReceive = false;
                LoopSend = true;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }

        while (LoopSend == true || InternalLoop < 2)
        {
            try
            {
                InternalLoop += 1;
                if (Packettosend == "ALIVE")
                {
                    Byte[] sendBytes1 = { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 };
                    networkStream.Write(sendBytes1, 0, sendBytes1.Length);
                    networkStream.Flush();

                    LoopReceive = true;
                    LoopSend = false;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }
    }
}

【问题讨论】:

  • 您所在的级别没有数据包,只有流。假设您正在将数据写入磁盘,将文件复制到另一台计算机并读取它。你怎么知道他在第一次 Write 调用中用拳头电脑写了多少?
  • Read 的返回值至关重要。这是知道缓冲区中实际有多少数据的唯一方法。为什么这两个循环?你只需要写来响应读取,你只需要一个循环。
  • Luaan,感谢关于双循环的提示。我解决了这个问题,看起来不错。
  • Luaan,感谢关于双循环的提示。我解决了这个问题,看起来不错。关于Read的返回,你是什么意思?我真的是从 Tcp 开始的,没有明白你的意思。
  • AcceptTcpClient 一起等待 客户端连接。仅在外部外循环执行此操作。顺便说一句,while (x==true)while (x) 相同。

标签: c# tcpclient


【解决方案1】:

您没有收到第二个数据包的原因是这一行:

clientSocket = serverSocket.AcceptTcpClient();

此调用等待 客户端连接到您服务器的侦听器套接字。

将此行移到您的外部循环之外,以仅接受一个客户端并在您的循环中仅使用该单个 clientSocket

(我想添加详细信息,但我在路上,很难在手机上输入所有内容...)

【讨论】:

  • René,我按照你说的做了修改,效果很好。但是现在我正在考虑如何以这种方式同时处理多个连接。我的意思是,如果有 2 个客户端连接到我的服务器。是否可以在不断开其中一个回复另一个的情况下同时处理两者?
  • @MarkJohansen 是的,但这个问题有点过于宽泛,无法在评论中回答。 Stack Overflow 是一个问答网站,所以如果您有一个新的(最好是具体)问题,请打开一个新问题。
  • René,你给我的解决方案奏效了。我进行了一些搜索以弄清楚如何将多个客户端放入同一服务器,现在已经很好了。感谢您的支持,祝您新年快乐;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-13
  • 1970-01-01
相关资源
最近更新 更多