问题标签 [networkstream]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
3 回答
11094 浏览

c# - 您如何等待网络流读取数据?

我的应用程序中有一个工作线程,负责三件不同的事情。我写的队列中出现了两个作业的请求,当请求出现在网络流上时,另一个作业被激活。我希望我的工作线程在没有工作要做时等待。这对于两个队列来说很容易,因为它们公开了一个在它们有项目时设置的 ManualResetEvent,但是 NetworkStream 似乎没有这个。NetworkStream 已从 TcpClient 检索。

我所追求的是看起来像这样的代码:

有谁知道当 NetworkStream 有数据时设置 WaitHandle 的方法?

0 投票
9 回答
67130 浏览

c# - 如何检查 TcpClient 连接是否关闭?

我正在玩弄 TcpClient 并试图弄清楚如何在连接断开时使 Connected 属性为 false。

我试着做

但是如果 TcpClient 断开连接,它仍然不会显示我。你将如何使用 TcpClient 来解决这个问题?

0 投票
3 回答
5602 浏览

.net - StreamWriter 不会刷新到 NetworkStream

使用 aStreamWriter写入 a NetworkStream,并使用 aStreamReader读取响应。该应用程序正在向新闻服务器发送命令和读取响应。

简化代码(无错误处理等):

最后一行的代码块,大概是在等待网络流发送响应。

我可以通过使用设置超时循环来避免挂起应用程序serverReader.Peek(),但我总是会超时;我从来没有得到回应。

如果我直接 telnet 到服务器和端口并输入命令,我会立即得到响应。

如果我serverWriter.Flush()明确调用,而不是使用该AutoFlush属性,我仍然会阻塞并且永远不会得到响应。

任何想法为什么我没有使用这种方法得到对服务器的响应?

谢谢!

解决:

上面的代码确实对我有用,所以我回去并在该代码的基础上构建了不起作用的代码。

在挂起的代码中,我仍在使用带有 serverReader.Peek() 的超时循环。Peek() 总是返回 -1,即使缓冲区中有数据要读取!!用对 ReadLine() 的阻塞调用替换 Peek() 循环可以解决我的问题。

我把超时循环放在最初是因为应用程序是多线程的,我不想阻塞。我将不得不重新审视这个问题,看看如何在不使用 Peek() 的情况下解决线程计时问题。

谢谢大家,很好的答案!

0 投票
1 回答
2873 浏览

c# - NetworkStream.CanRead 返回 true 但缓冲区不返回值

我有一个 do while 循环,它从一个对象中读取一个缓冲区,NetworkStreamwhile 条件是networkStream.CanRead只要它可以读取,它就应该继续从缓冲区中读取。唯一的问题是当我从缓冲区读取并转换为字符串时,其中没有任何内容。即它是空的。

为什么会这样?

这是一个 ASP.NET(VS2005) 应用程序

@dtb 代码信息:

我正在传递一个NetworkStream对象networkStream

有趣的是,如果它重新连接并再次连接,发送/读取工作正常。这实际上是发送的问题(我在这里没有例外)或NetworkStream对象的重用。这在测试 TCP 服务器上本地运行良好,但是在生产(Windows Server 2003)中我遇到了上述问题(即无法从流中读取任何内容——直到我实际超时(退出循环)之后10s)

0 投票
3 回答
27677 浏览

c# - 关闭 TCP 连接的正确方法是什么

我有一个 TcpClient 对象,它使用其底层 NetworkStream.Write() 向服务器发送一些数据。因此,我有:

现在,当按下按钮时,连接应该关闭。关闭连接的正确方法是什么?MSDN 文档说关闭 TcpClient(使用 .Close())实际上并没有关闭套接字,只关闭了 TcpClient 资源(这至少是我理解文档的方式)。

那么,执行下一个代码会正确关闭连接吗?

这是否足够,或者我应该首先(以某种方式)检查流(或服务器)是否可以关闭(以防连接半开或其他情况)......

更重要的是,NetworkStream.Close()MSDN 文档声明它释放资源(甚至是套接字),所以也许关闭流就足够了,因为我在那之后阻止使用 TcpClient。

什么是正确的方法?

0 投票
2 回答
10039 浏览

sockets - 在使用 NetworkStream 类时检测客户端 TCP 断开连接

有朋友来找我的一个问题:在连接的服务器端使用NetworkStream类时,如果客户端断开连接,NetworkStream检测不到。

精简后,他的 C# 代码如下所示:

该代码有效,因为客户端可以成功连接并且服务器可以读取发送给它的数据。但是,如果远程客户端调用 tcpClient.Close(),服务器不会检测到断开连接 - client.Connected 保持为真,而 ns.DataAvailable 为假。

对 Stack Overflow 的搜索提供了一个答案——因为没有调用 Socket.Receive,所以套接字没有检测到断开连接。很公平。我们可以解决这个问题:

(为简洁起见,我省略了异常处理代码。)

此代码有效,但是,我不会将此解决方案称为“优雅”。我知道的问题的另一个优雅解决方案是为每个 TcpClient 生成一个线程,并允许 BinaryFormatter.Deserialize (née NetworkStream.Read) 调用阻塞,这将正确检测断开连接。但是,这确实会产生为每个客户端创建和维护线程的开销。

我觉得我错过了一些秘密的、很棒的答案,它会保留原始代码的清晰度,但避免使用额外的线程来执行异步读取。虽然,也许 NetworkStream 类从来没有为这种用途而设计。任何人都可以解释一下吗?

更新:只是想澄清一下,我有兴趣看看 .NET 框架是否有一个解决方案,涵盖了 NetworkStream 的这种使用(即轮询避免阻塞)——显然可以做到;NetworkStream 可以很容易地包装在提供该功能的支持类中。看起来很奇怪,该框架本质上要求您使用线程来避免阻塞 NetworkStream.Read,或者窥视套接字本身以检查断开连接 - 几乎就像它是一个错误。或者可能缺少某个功能。;)

0 投票
2 回答
1851 浏览

.net - NetworkStream.Read 延迟.Net

我有一个继承自 TcpClient 的类。在该课程中,我有一种处理响应的方法。在我调用的那个方法中,我使用 MyBase.GetStream 获取 NetworkStream 并在其上调用 Read。

这很好用,除了第一次调用读取块的时间太长。太长了,我的意思是套接字已经接收到大量数据,但在达到任意限制之前不会读取它。我可以看到它使用数据包嗅探器 WireShark 收到了大量数据。

我已将接收缓冲区设置为少量,并且非常少量(例如只有几个字节)无济于事。我对传递给 read 方法的缓冲区字节数组做了同样的事情,但它仍然延迟。

或者换一种说法。我下载600k。下载需要 5 秒(与服务器的连接速度略高于 100k/秒,这是有道理的)。初始读取调用需要 2-3 秒,并告诉我只有 256 个字节可用(256 是接收缓冲区和我读入的数组的大小)。然后神奇地,其他几十万字节可以在 256 字节块中读取,每个块只需几个进程滴答。使用数据包嗅探器,我知道在最初的 2-3 秒内,套接字收到的不仅仅是 256 个字节。我的连接在 3 秒内不是 0.25k/秒,在 2 秒内不是 400k。

当它们进入时,如何从套接字中获取字节?

0 投票
2 回答
4094 浏览

multithreading - 读取时的 TcpClient 和 StreamReader 块

这是我的情况:

我正在编写一个聊天客户端来连接到聊天服务器。我使用 TcpClient 创建连接并从中获取 NetworkStream 对象。我使用 StreamReader 和 StreamWriter 来回读取和写入数据。

这是我读到的样子:

这工作得很好,花花公子。在我的主程序中,我创建了一个线程,该线程不断调用此 Read 方法以查看是否有数据。下面是一个例子。

这工作得很好。当我想关闭应用程序时,问题就来了。我收到来自 UI 的关闭命令,并告诉侦听线程停止侦听(即停止调用此读取函数)。我调用 Join 并等待这个子线程停止运行。像这样:

问题是它永远不会停止运行!我进入了代码,监听线程被阻塞了,因为 Read() 方法被阻塞了。Read() 只是坐在那里不返回。因此,线程永远不会有机会休眠 1 毫秒然后被中断。

我敢肯定,如果我让它坐得足够长,我会得到另一个数据包并有机会让线程休眠(如果它是一个活动的聊天室或从服务器获得一个 ping)。但我不想依赖那个。如果用户说关闭我想关闭它!

我发现的一种替代方法是使用 NetworkStream 的DataAvailable方法,这样我就可以在调用 StreamReader.Read() 之前对其进行检查。这不起作用,因为它不可靠,并且在从服务器读取数据包时丢失了数据。(因为我无法正确登录等等)

关于如何优雅地关闭这个线程的任何想法?我不想在监听线程上调用 Abort() ......

0 投票
1 回答
6280 浏览

c# - 表示远程主机已关闭连接的 NetworkStream.Read 的替代方案?

关于使用该类处理 TCP/IP 连接,除了等待方法返回 0TcpClient之外,还有其他方法可以检查远程主机是否关闭了连接?NetworkStream.Read

0 投票
2 回答
6009 浏览

.net - 获取通过网络发送到 TCPlistener/networkstream vb.net 的数据长度

这似乎是最明显的事情,但我只是不知道如何使用 TCPClient 和 TCPListener 获取通过网络发送的字节长度?到目前为止,这是我的代码:

我需要获取网络流的长度来设置要读取数据的字节数组的大小。但是 networkStream.length 不受支持并且不起作用并引发 Notsupportedexception。

我能想到的唯一另一种方法是在发送数据之前发送数据的大小,但这似乎很长。