【问题标题】:Concurrent access of Network Stream on the same Machine同一台机器上同时访问网络流
【发布时间】:2017-10-17 14:49:48
【问题描述】:

来自this answerDocs,它说对于并发流访问,如果有一个唯一的读取线程和一个唯一的写入线程,则可以毫无问题地执行读取和写入。

我有以下设置,如下图所示:

我有 2 个独立的服务 Tester ServiceMy Service。他们每个人都有一个Server 和一个Client。每个服务器和客户端都有 2 个任务 WriterTaskReaderTask

我面临的问题是,经过一段时间后,客户给出了IOException 10060。事实上,另一边的服务器运行良好。

现在,文档说有一个用于读/写操作的唯一线程,如果它在同一台机器上会不会有问题?

以前有没有人遇到过类似的情况?

服务器阅读器:

    private void ReaderTask(NetworkStream stream)
    {
        while (true)
        {
            // Some code
            try
            {
                if (stream.CanRead)
                {
                    var readTask = Task.Run(() =>
                    {
                        MyObj message = null;
                        try
                        {
                            message = Deserialize<MyObj>(stream);
                            Console.WriteLine("ReaderTask: Read");
                            // Some code
                        }
                        catch (IOException e)
                        {
                            Console.WriteLine("ReaderTask: " + e.Message);
                        }
                        return message;
                    });
                    while(!readTask.Wait(1000))
                    {
                        Console.WriteLine("ReaderTask: Wait 1000");
                    }
                    if (readTask.Result != null)
                    {
                        Console.WriteLine("ReaderTask: Message received" + readTask.Result.toString());
                    }
                }
            }
            catch (IOException e)
            {
                Console.WriteLine("ReaderTask: " + e.Message);
            }
        }
    }

客户作家:

    private void WriterTask(NetworkStream stream)
    {
        while (true)
        {
            // Some code
            try
            {
                if (stream.CanWrite)
                {
                    // message = getMessage();
                    Serialize(stream, message);
                    Console.WriteLine("WriterTask: Write");
                    // Some code
                }
            }
            catch (IOException e)
            {
                Console.WriteLine("WriterTask: " + e.Message);
            }
            Thread.Sleep(1000);
        }
    }

【问题讨论】:

  • 是的,我遇到了类似的情况,问题出在我的代码中,与读写线程之间的分离无关。你怎么知道“服务器运行良好”?当前是否有线程阻塞正在崩溃的客户端的NetworkStream.Read() 操作?
  • @C.Evenhuis “服务器运行良好” - 服务器的读取器和写入器任务正在生成日志。所以我知道他们很好。但是服务器的读取器任务正在读取无限期阻塞的异步任务中的流。我在下面的答案中提供了详细信息。如果您有更多信息,最好发布答案并填写更多详细信息。

标签: c# multithreading sockets


【解决方案1】:

我发现了问题所在。

我没有从我的服务器接收任何数据,因为我没有像 client.ReceiveTimeout = 2000 这样在客户端上设置接收超时。因此,服务器会在读取调用时阻止它的 ReaderTask

我不能 100% 确定为什么当客户端的 WriterTask 写入流时,服务器的 ReaderTask 什么也不读取并保持阻塞状态。但是一旦我对服务器中的客户端对象设置了超时,一切都开始正常运行了。

那么,如果具有唯一ReaderTaskWriterTask 的应用程序在同一台机器上,会不会有问题?当您使用接收超时时,完全没有问题。如果没有接收超时,它就无法正常工作(至少在我的情况下)。

【讨论】:

  • 如果客户端发送数据,服务器的Read() 操作将不再阻塞 - 从您的描述来看,客户端似乎没有发送任何内容,因为它正在等待数据。但是没有任何代码就很难说。您不必设置 ReceiveTimeout 来解决此问题。
  • @C.Evenhuis 在没有接收超时的情况下,在一些读取和写入之后,服务器的读取器会突然在while(!readTask.Wait(1000)) 中无限循环,而任务在message = Deserialize&lt;MyObj&gt;(stream); 处被阻塞。即使客户的作家已经写在流上——我从日志中验证了这一点。但是,现在,我不知道为什么会发生这种情况。请参阅我的问题以获取相关代码。
猜你喜欢
  • 2017-09-04
  • 1970-01-01
  • 2017-04-28
  • 1970-01-01
  • 2023-03-21
  • 1970-01-01
  • 1970-01-01
  • 2020-07-06
  • 2023-03-13
相关资源
最近更新 更多