c# - 如何使用单个 TcpClient 实例从客户端向服务器发送多个字符串消息?

标签 c# sockets tcpclient

我有单独的客户端和服务器控制台应用程序。我只是尝试从客户端向服务器发送一个字符串,并让服务器使用 TcpClient 将字符串写入控制台。我可以发送一条消息就好了,但是当我抛出 while 时循环到客户端应用程序以尝试在不关闭 TcpClient 的情况下发送多条消息,服务器不会向控制台写入任何内容。

//Server
using (TcpClient client = listener.AcceptTcpClient())
{
    NetworkStream ns = client.GetStream();
    byte[] buffer = new byte[1024];
    while (true)
    {
        if (ns.DataAvailable)
        {
            int bytesRead = 0;
            string dataReceived = "";
            do
            {
                bytesRead = ns.Read(buffer, 0, buffer.Length);
                dataReceived += Encoding.UTF8.GetString(buffer, 0, bytesRead);
            }
            while (bytesRead > 0);
            Console.WriteLine($"Message:{ dataReceived }\n");
        }
    }
}

//Client
using (TcpClient client = new TcpClient(hostname, port))
{
    if (client.Connected)
    {
        Console.WriteLine("Connected to server");
        NetworkStream ns = client.GetStream();
        string message = "";
        //Removing this while loop I can send a single message that the server will write to console
        //but with the loop present the server does not write anything
        while (true)
        {
            message = Console.ReadLine();
            byte[] messageBytes = UTF8Encoding.UTF8.GetBytes(message);
            ns.Write(messageBytes);
            Console.WriteLine($"Message Sent! ({ messageBytes.Length } bytes)");
        }
    }
}
我对学习套接字很感兴趣,两天来一直在倾诉 SO 问题和 MSDN 文档,但无法弄清楚为什么它没有按我的意图工作。即使提交问题,我也觉得有点傻,因为我确定这是我不理解的基本问题。有人可以给我一些知识吗?
解决方案
//Server
using (TcpClient client = listener.AcceptTcpClient())
{
    NetworkStream ns = client.GetStream();
    StreamReader sr = new StreamReader(ns);
    string message = "";
    while (true)
    {
        message = sr.ReadLine();
        Console.WriteLine(message);
    }
}

//Client
using (TcpClient client = new TcpClient(hostname, port))
{
    if (client.Connected)
    {
        Console.WriteLine("Connected to server");
        NetworkStream ns = client.GetStream();
        StreamWriter sw = new StreamWriter(ns) {Autoflush = true};
        string message = "";
        while (true)
        {
            message = Console.ReadLine();
            sw.WriteLine(message);
        }
    }
}

最佳答案

如果您调试服务器,您会看到它确实接收数据。您只是没有显示数据,因为您的服务器所做的唯一输出是在返回的字节数为 0 的循环之后:Console.WriteLine($"Message:{ dataReceived }\n"); .当底层套接字关闭时,字节数只会为 0。这永远不会发生,因为您的客户陷入了无限循环。
对于像这样的基于文本的简单客户端/服务器示例,更好的方法是使用 StreamWriterStreamReader带有基于行的消息,即 WriteLine()ReadLine() .然后换行符作为消息分隔符,您的服务器每次收到新行时都可以写入消息。
另请注意,在上面的示例中,您假设每个数据块仅包含完整的字符。但是您使用的是 UTF8,其中字符可以是两个或更多字节,并且 TCP 不保证发送的字节是如何分组的。使用 StreamWriterStreamReader也会修复这个错误,但如果你想自己明确地做,你可以使用 Decoder类,它将缓冲部分字符。
有关如何正确实现这样的简单客户端/服务器网络程序的一些示例,请参阅以下帖子:
.NET Simple chat server example
C# multithreading chat server, handle disconnect
C# TcpClient: Send serialized objects using separators?

关于c# - 如何使用单个 TcpClient 实例从客户端向服务器发送多个字符串消息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67747156/

相关文章:

c# - 基于事件的多线程生产者-消费者?

c# - 错误 : 'Subscript indices must either be real positive integers or logicals' when using Matlab . NET 生成器

c# - 如何让 VS 假定所有内容默认都是公开的

c# - 设置 DataGrid 列的样式

python - 是否有任何 python 库可以抽象基于 IP 的传输——TCP、UDP、SCTP、TLS 等?

c# - TCP/IP 条码读取器仅获取半个条码

c# - 如何安全地结束 NetworkStream.Read()? (在 C# 或 VB.net 中)

java - 如何发送认证字符串建立TCP连接?

Java、套接字连接和 HTTP 请求/响应

java - 我可以在使用 Java Socket 实现的网络服务器上使用任何身份验证机制吗?