Quv*_*Quv 1 c# sockets networkstream tcpclient
我写了一个类,试图读取服务器发送的字节数据,当我的应用程序结束时,我也希望循环结束,但是NetworkStream.Read()如果没有数据可用,它似乎等待.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Threading;
using System.Net;
using System.Threading.Tasks;
namespace Stream
{
class Program
{
private static TcpClient client = new TcpClient("127.0.0.1", 80);
private static NetworkStream stream = client.GetStream();
static void Main(string[] args)
{
var p = new Program();
p.Run();
}
void Run()
{
ThreadPool.QueueUserWorkItem(x =>
{
while (true)
{
stream.Read(new byte[64], 0, 64);
}
});
client.Close();
// insert Console.ReadLine(); if you want to see an exception occur.
}
}
}
Run Code Online (Sandbox Code Playgroud)
有了这段代码,我们就可以了
System.IO.IOException 说"无法从传输连接读取数据:现有连接被远程主机强行关闭",ObjectDisposedException 说"无法访问已处置的对象",或System.IO.IOException 说"通过调用WSACancelBlockingCall来中断阻塞操作". 那我怎么能安全地结束这个方法呢?
这可能有所帮助
void Run() {
ThreadPool.QueueUserWorkItem(ReadLoop);
}
void ReadLoop(object x) {
if (stream.DataAvailable)
stream.Read(new byte[64], 0, 64);
else
Thread.Sleep(TimeSpan.FromMilliseconds(200));
if (Finished)
client.Close();
else if (!Disposed && !Finished)
ThreadPool.QueueUserWorkItem(ReadLoop);
}
Run Code Online (Sandbox Code Playgroud)
您需要在真实班级中自己管理完成和处置.
从我在运行程序时可以看到,第一个异常"无法从传输连接中读取数据......"不是由Stream.Read引发的,而是由TcpClient的构造函数引发的,很可能是由于存在这样的事实.没有服务器接受127.0.0.1:80上的连接.
现在,如果你想在Stream.Read上很好地结束,我会异步进行.通过这种方式,您可以捕获在Read和清理程序期间抛出的任何异常.这是您的程序的修改版本:
using System;
using System.Net.Sockets;
namespace Stream
{
class Program
{
private static TcpClient client;
private static NetworkStream stream;
static void Main(string[] args)
{
var p = new Program();
p.Run();
}
void Run()
{
try
{
client = new TcpClient("127.0.0.1", 80);
stream = client.GetStream();
byte[] buffer = new byte[64];
stream.BeginRead(buffer, 0, buffer.Length, new AsyncCallback(OnRead), buffer);
client.Close();
Console.ReadKey();
}
catch (Exception)
{
//...
}
}
void OnRead(IAsyncResult result)
{
try
{
stream.EndRead(result);
byte[] buffer = result.AsyncState as byte[];
if (buffer != null)
{
//...
}
// continue to read the next 64 bytes
buffer = new byte[64];
stream.BeginRead(buffer, 0, buffer.Length, new AsyncCallback(OnRead), buffer);
}
catch (Exception)
{
// From here you can get exceptions thrown during the asynchronous read
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
15007 次 |
| 最近记录: |