【问题标题】:full duplex Tcp data exchange c#全双工 TCP 数据交换 c#
【发布时间】:2014-11-11 06:30:55
【问题描述】:

我在两台主机之间有一个全双工连接,它们与一个始终侦听 NetworkStream.Read() 的线程交换数据。如何优雅地关闭连接以避免:

1-两侧read()函数的死锁

2- 读取线程的 abort() [安全关闭它们]

我想用 SocketShutdown.Send 关闭连接,但它是如何工作的?它解锁了另一边的 Read().. 文档中的内容并不多。

谢谢

【问题讨论】:

  • 恕我直言,这里是开始学习套接字的最佳地点之一:tangentsoft.net/wskfaq MSDN 文档也有您需要的信息,如果您有耐心的话。我承认那里的代码示例不是最好的,但它们通常可以工作并说明如何编写某些类型的网络代码。很久以前,我写了一篇文章,旨在向 .NET 程序员介绍基本的网络技术:blogs.msmvps.com/duniho/2008/08/19/… 也许你会发现它比 MSDN 上的例子更有用。

标签: c# networkstream


【解决方案1】:

一个简单的网络交换看起来像这样:

Server: create socket
Server: listen on socket
Client: create socket
Client: connect to server's address
Server: accept connection, which returns a new socket to use for that connection
Client: receive new socket from result of connect operation

现在连接已建立。将有一些定义的协议用于相互通信。该协议将决定谁开始。它可以是任何一个,但对于这个例子,我们假设它是客户端:

Client: send some data
Server: receive the data
Server: send a response
Client: receive the data
Client: shutdown with "send" (but still be prepared to receive)
Server: receive completes with 0 (indicates no more data will be sent by client)
Server: shutdown with "both"
Client: receive completes with 0 (indicates no more data will be sent by server)
Server & Client: close sockets

回答您的具体问题:

  1. How is deadlock avoided? 这里没有死锁的可能性。服务器和客户端通常都是使用异步网络 API 编写的。但是如果定义的协议是一个简单的请求/响应协议(例如 HTTP),即使这不是严格要求的。每一端都可以是单线程的,根据协议在发送和接收之间交替。

  2. '你如何中止阅读线程?'你没有。如果您确实将整个线程专用于从套接字读取数据(这确实不是很好的设计),那么当线程看到一个长度为 0 字节的接收操作完成时,该线程就会简单地退出。

【讨论】:

  • 为什么“这真的不是很好的设计”?使用回调函数更好吗?
  • 是的,要么是那个,要么是新的async/await 模式。 .NET 中支持多种不同的机制,通常用于异步处理 I/O,特别是用于套接字。正确使用这些 API 可确保有效利用资源,而将整个线程专用于单个操作则不能。
猜你喜欢
  • 2015-04-14
  • 2015-07-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多