模式是什么和/或如何更改以下代码,以便可以从服务器或客户端优雅地关闭连接,而不需要异常处理。
编辑:,我将原始代码和应答代码移到了要旨。
原始失败示例:迁移到这里:original.cs
当前工作答案:answer.cs
class Channel
{
private readonly TcpClient client;
private readonly NetworkStream stream;
private readonly string name;
private readonly ManualResetEvent quit = new ManualResetEvent(false);
public Channel(string name, TcpClient client)
{
this.name = name;
this.client = client;
stream = client.GetStream();
}
public void Run()
{
Console.WriteLine(name + ": connected");
byte[] buffer = new byte[client.Client.ReceiveBufferSize];
stream.BeginRead(buffer, 0, buffer.Length, this.Read, buffer);
var writer = new StreamWriter(stream, Encoding.ASCII);
while (true)
{
var line = Console.ReadLine();
if (String.IsNullOrEmpty(line) || !this.client.Connected) break;
writer.WriteLine(line);
writer.Flush();
}
if (client.Connected)
{
Console.WriteLine(name + " shutting down send.");
client.Client.Shutdown(SocketShutdown.Send);
Console.WriteLine(name + " waiting for read to quit.");
quit.WaitOne();
}
else
{
Console.WriteLine(name + " socket already closed");
}
Console.WriteLine(name + " quit, press key to exit.");
Console.ReadKey();
}
private void Read(IAsyncResult result)
{
var bytesRead = this.stream.EndRead(result);
if (bytesRead == 0)
{
Console.WriteLine(name + " read stopped, closing socket.");
this.client.Close();
this.quit.Set();
return;
}
var buffer = (byte[])result.AsyncState;
Console.WriteLine(name + " recieved:" + Encoding.ASCII.GetString((byte[])result.AsyncState, 0, bytesRead));
stream.BeginRead(buffer, 0, buffer.Length, this.Read, buffer);
}
}发布于 2009-08-26 19:16:25
在调用Socket.Shutdown()之前使用Socket.Close()。等待关闭处理完成(例如,ReceiveAsync()将返回0字节)。
发布于 2009-08-26 19:04:50
TcpClient实现了IDisposable,所以您应该能够像这样使用它,然后就不用担心关闭客户机了-- using语句应该为您做这件事,不管是否抛出异常:
class Client
{
static void Main(string[] args)
{
using (TcpClient client = new TcpClient(AddressFamily.InterNetwork))
{
Console.WriteLine("client: created, press key to connect");
Console.ReadKey();
client.Connect(IPAddress.Loopback, 5000);
var channel = new Channel("client", client);
channel.Run();
}
}
}也就是说,通常实现IDisposable的CLR类型会明确表示它们关闭了文档中的特定底层资源(例如:SqlConnection),但在这个问题上的TcpClient 文档却异常安静--您可能需要先测试一下。
发布于 2009-08-26 19:18:40
我已经有一段时间没有做套接字了,但我记得您必须为它们调用while ()。
我想,.NET的等价物应该是socket.Shutdown(SocketShutdown.Both)
https://stackoverflow.com/questions/1336709
复制相似问题