如何从流中获取TCP服务器的最后一条消息?

时间:2012-11-18 15:32:19

标签: c# stream-socket-client

TcpClient client = new TcpClient();
client.Connect(IPAddress.Parse(HOST_IP), HOST_PORT);
Stream stream = client.GetStream();
var reader = new StreamReader(stream);
var writer = new StreamWriter(stream);
writer.AutoFlush = true;
while (true) {
  string line;
  while((line = reader.ReadLine())!=null) {
    Console.WriteLine(line);
  }
  writer.WriteLine(Console.ReadLine());
}

我的服务器向客户端发送两个字符串:

var stream = new NetworkStream(soc);
var reader = new StreamReader(stream);
var writer = new StreamWriter(stream);
writer.AutoFlush = true
writer.WriteLine("Welcome: ");
writer.WriteLine("Bla...: ");
reader.ReadLine();

我的客户端将显示

Welcome
Bla..

但它没有运行命令writer.WriteLine(Console.ReadLine());

1 个答案:

答案 0 :(得分:1)

您需要决定这一切将如何关闭,但正如评论中所示,我建议您使用第二个线程,以使双方(客户端上的发送和接收方)能够无需运行阻挡:

TcpClient client = new TcpClient();
client.Connect(IPAddress.Parse(HOST_IP), HOST_PORT);
Stream stream = client.GetStream();
var reader = new StreamReader(stream);
var writer = new StreamWriter(stream);
writer.AutoFlush = true;
var t = new Thread(() => {
    while(true) {
        writer.WriteLine(Console.ReadLine());
    }
});
t.Start();
while (true) {
  string line;
  while((line = reader.ReadLine())!=null) {
    Console.WriteLine(line);
  }
}

与您的评论不同,您不希望在循环中创建线程 - 总是有可能一方(例如从服务器接收)可以多次处理而无需为另一方工作(发送到服务器)。

对于关闭,我通常会在关闭时创建一个ManualResetEvent(在适当的条件下设置)。然后我将测试事件对象作为while循环的条件。

唯一的问题是Console.ReadLine()正在阻止。因此,除非接收到新输入,否则您的读取控制台/发送到服务器线程将不会看到已设置关闭事件。如果您的读/发线程不负责启动关闭,您可以使它成为后台线程(假设它不会改变任何全局状态)然后只处理关闭您的接收/写入线程(即主线程)在适当的时候。