我有单独的客户端和服务器控制台应用程序。我只是尝试从客户端向服务器发送一个字符串,并让服务器使用 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。这永远不会发生,因为您的客户陷入了无限循环。
对于像这样的基于文本的简单客户端/服务器示例,更好的方法是使用 StreamWriter
和 StreamReader
带有基于行的消息,即 WriteLine()
和 ReadLine()
.然后换行符作为消息分隔符,您的服务器每次收到新行时都可以写入消息。
另请注意,在上面的示例中,您假设每个数据块仅包含完整的字符。但是您使用的是 UTF8,其中字符可以是两个或更多字节,并且 TCP 不保证发送的字节是如何分组的。使用 StreamWriter
和 StreamReader
也会修复这个错误,但如果你想自己明确地做,你可以使用 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/