我正在玩TcpClient,我试图弄清楚如何在连接断开时使Connected属性为false.
我试过了
NetworkStream ns = client.GetStream();
ns.Write(new byte[1], 0, 0);
Run Code Online (Sandbox Code Playgroud)
但是如果TcpClient断开连接,它仍然不会显示给我.你会如何使用TcpClient进行此操作?
我想知道在使用TPL TaskFactory.FromAsync和使用TaskFactory.StartNew阻塞版本的方法之间是否存在性能影响.我正在编写一个TCP服务器,它将支持不超过100个并发连接.在使用第一个选项编写代码并使用continue来链接多个读写操作之后,我留下了丑陋,难以调试的代码.
我相信用同步版本编写代码然后用Task包装它会降低复杂性并提高可测试性,但是我担心这样做的性能影响.
例如,这两个调用之间是否存在任何性能差异:
NetworkStream stream;
byte[] data;
int bytesRead;
//using FromAsync
Task<int> readChunk = Task<int>.Factory.FromAsync (
stream.BeginRead, stream.EndRead,
data, bytesRead, data.Length - bytesRead, null);
//using StartNew with blocking version
Task<int> readChunk2 = Task<int>.Factory.StartNew(() =>
stream.Read(data, bytesRead, data.Length - bytesRead));
Run Code Online (Sandbox Code Playgroud) 我有一个ac#应用程序,我使用自定义FTP库.现在我使用Socket.Send发送数据,但我想知道用套接字启动NetworkStream是否更好,而是使用NetworkStream.Write.
使用一个优于另一个是否有任何优势?
我正在使用Moq和NUnit作为单元测试框架.
我写了一个方法,给出一个NetworkStream对象作为参数:
public static void ReadDataIntoBuffer(NetworkStream networkStream, Queue dataBuffer)
{
if ((networkStream != null) && (dataBuffer != null))
{
while (networkStream.DataAvailable)
{
byte[] tempBuffer = new byte[512];
// read the data from the network stream into the temporary buffer
Int32 numberOfBytesRead = networkStream.Read(tempBuffer, 0, 512);
// move all data into the main buffer
for (Int32 i = 0; i < numberOfBytesRead; i++)
{
dataBuffer.Enqueue(tempBuffer[i]);
}
}
}
else
{
if (networkStream != null)
{
throw new ArgumentNullException("networkStream");
}
if (dataBuffer …Run Code Online (Sandbox Code Playgroud) 目前,NetworkStream.PeekC#中没有一种方法.实现这样一个方法的最佳方法是什么,NetworkStream.ReadByte除了返回byte的实际上没有从Stream?
我只需N要从a 读取字节,SslStream但如果在超时之前没有收到任何字节,则取消,同时将流保持在有效状态,以便稍后再试.(*)
对于非SSL流,这可以很容易地完成,即NetworkStream只需使用其ReadTimeout属性,这将使流在超时时抛出异常.不幸的是,这种方法不适SslStream用于官方文档:
SslStream假定当从内部流抛出一个IOException时,超时以及任何其他IOException将被其调用者视为致命的.超时后重用SslStream实例将返回垃圾.应用程序应该关闭SslStream并在这些情况下抛出异常.
[更新1]我尝试了一种不同的方法:
task = stream->ReadAsync(buffer, 0, buffer->Length);
if (task->Wait(timeout_ms)) {
count = task->Result;
...
}
Run Code Online (Sandbox Code Playgroud)
但是如果Wait()返回则这不起作用false:ReadAsync()稍后再次调用它会抛出异常:
抛出异常:System.dll Tests.exe中的"System.NotSupportedException"警告:0:从套接字读取失败:System.NotSupportedException:当另一个读取操作挂起时,无法调用BeginRead方法.
[更新2]我尝试另一种方法,通过调用实现超时Poll(timeout, ...READ)基础上的TcpClient插座:如果返回true,然后调用Read()上SSlStream,或者如果它返回false,然后我们有一个超时.这也不起作用:因为SslStream可能使用它自己的内部中间缓冲区,即使还有数据需要读取,Poll()也可以返回.falseSslStream
[更新3]另一种可能性是编写一个自定义Stream子类,它位于NetworkStream和之间SslStream并捕获超时异常并返回0字节SslStream.我不知道如何做到这一点,更重要的是,我不知道是否返回0字节读取SslStream仍然不会以某种方式破坏它.
(*)我试图这样做的原因是,与非安全或安全套接字的超时同步读取是我已经在iOS,OS X,Linux和Android上用于某些跨平台代码的模式.它适用于.NET中的非安全套接字,因此唯一的情况是SslStream.
我正在使用NetworkStream和TcpClient使用BeginRead异步接收数据.我需要对此操作应用超时,以便在指定的时间后读取将被中止.
据我所知,NetworkStream或TcpClient不支持 - 有一个ReceiveTimeout属性,但这似乎只适用于同步等效 - 'Read'.
甚至底层的Socket类似乎也不支持其BeginReceive方法中的超时.
我已经搜索过这个问题,我看到的唯一建议的解决方案是设置另一个后台线程来取消操作,如果它在超时期限内没有完成.这看起来像是一个可怕的黑客.当然有更好的方法吗?
我正在阅读有关TcpClient.Close()的文档并注意到这一点:
调用此方法最终将导致关联的Socket关闭,并且还将关闭用于发送和接收数据的关联NetworkStream(如果已创建).
因此,纠正我,如果我错了,但是这说,如果一个调用Close()的TcpClient是,NetworkStream也将被关闭.
那么为什么在代码示例的末尾都会Close()被调用?
networkStream.Close();
tcpClient.Close();
Run Code Online (Sandbox Code Playgroud)
只打电话会一样tcpClient.Close();好吗?
我试图使用NetworkStream.ReadAsync()来读取数据,但我无法找到如何在调用时取消ReadAsync().对于后台,NetworkStream由连接的BluetoothClient对象(来自32Feet.NET蓝牙库)提供给我.
我正在尝试的当前get-it-working代码如下.
int bytesRead;
while (this.continueReading)
{
bytesRead = await this.stream.ReadAsync(this.buffer, 0, (int)this.buffer.Length);
Console.WriteLine("Received {0} bytes", bytesRead);
}
Console.WriteLine("Receive loop has ended");
Run Code Online (Sandbox Code Playgroud)
代码可以很好地接收数据,并且如果continueReading标志设置为false并且接收到数据,则将停止循环,但是在接收到数据之前,它将不会继续通过ReadAsync()行.我无法看到如何在不接收数据的情况下中止呼叫.
我知道ReadAsync的重载提供了一个CancellationToken,但是当NetworkStream没有覆盖默认的ReadAsync行为时,会忽略该令牌(请参阅具有取消令牌的NetworkStream.ReadAsync永远不会取消).
我尝试关闭底层流,这导致等待ReadAsync调用抛出ObjectDisposedException,底层蓝牙连接也被关闭.理想情况下,我不想完全切断与设备的连接,只是为了停止阅读.它似乎不是一种干净的方式,并且感觉不必拆除整个流只是为了中断va ReadAsync()调用.
有什么建议?
我试图读取通过机器的缓冲区中存在的所有数据,TCP/IP但我不知道为什么我没有得到所有数据,一些数据正在错过.这是我正在使用的代码..
using (NetworkStream stream = client.GetStream())
{
byte[] data = new byte[1024];
int numBytesRead = stream.Read(data, 0, data.Length);
if (numBytesRead > 0)
{
string str= Encoding.ASCII.GetString(data, 0, numBytesRead);
}
}
Run Code Online (Sandbox Code Playgroud)
请告诉我我缺少什么来从机器获取所有数据.提前致谢..
networkstream ×10
c# ×8
tcpclient ×4
.net ×2
asynchronous ×2
sockets ×2
async-await ×1
beginread ×1
beginreceive ×1
byte ×1
c#-4.0 ×1
dispose ×1
mocking ×1
moq ×1
peek ×1
sslstream ×1
stream ×1
task ×1
taskfactory ×1
tcp ×1
tcp-ip ×1
unit-testing ×1