C# 如何处理.NET中的套接字断开连接?
我正在构建一个(LAN)网络应用程序,因此由于各种可能的原因,连接总是有可能断开。我正试图想出一个好的设计来处理这个问题,这样它就不会影响应用程序的其余部分。我写了一个快速的东西来尝试这样做,但我认为它可以提高很多。我感谢您的帮助和经验,了解处理此问题的最佳方法 这是我的第一次尝试:C# 如何处理.NET中的套接字断开连接?,c#,.net,sockets,C#,.net,Sockets,我正在构建一个(LAN)网络应用程序,因此由于各种可能的原因,连接总是有可能断开。我正试图想出一个好的设计来处理这个问题,这样它就不会影响应用程序的其余部分。我写了一个快速的东西来尝试这样做,但我认为它可以提高很多。我感谢您的帮助和经验,了解处理此问题的最佳方法 这是我的第一次尝试: class ConnectionWrapper { NetworkStream stream; StreamReader reader; Endpoint endPoint; boo
class ConnectionWrapper {
NetworkStream stream;
StreamReader reader;
Endpoint endPoint;
bool endOfStream;
int maxRetries = 5;
public void connect() {
// ... code to initialize a (TCP) socket to endPoint
this.stream = new NetworkStream(socket, true);
this.reader = new StreamReader(stream);
}
string readNextMsg() {
try {
string msg = reader.ReadLine();
if (msg == "EOF") endOfStream = true;
return msg;
}
catch (IOException e) {
Exception ex = e;
while (maxRetries-- > 0) {
try { connect(); ex = null; }
catch (Exception e2) { ex = e2; }
}
if (x != null) throw ex;
}
}
}
不是很优雅,也可能不是最好的。你能分享一下你的经验吗,甚至可以建议一个现有的图书馆
谢谢。老实说,我认为您不应该让连接包装器包含处理自己的连接策略的逻辑。我认为这应该在这个类之外完成,特别是不要在catch语句中。使用某种ConnectionController对象来处理连接失败后是否应重试连接。我本来打算编辑我的文章,但这应该与我上一篇文章完全分开 在我看来,您的逻辑是完全错误的,您应该在ConnectionWrapper中有一个线程,它在StreamReader上旋转,提取消息并将它们放在队列中。然后,此队列将更改通知侦听器。然后监听器自己去检索数据,并决定需要对它们做什么
class ConnectionWrapper {
NetworkStream stream;
StreamReader reader;
Endpoint endPoint;
bool endOfStream;
int maxRetries = 5;
ArrayList arr;
public void connect() {
// ... code to initialize a (TCP) socket to endPoint
this.stream = new NetworkStream(socket, true);
this.reader = new StreamReader(stream);
}
private void initReceiverThread() {
String line;
while(stream.isConnected() && (line = reader.readLine()) != null) {
// notify observers of a change
arr.add(line);
}
}
}
这是伪代码,我警告你,我从来没有在C#中这样做过。典型的读卡器实际上是在等待readLine语句,所以while循环不会发疯。最好将initReceiverThread代码放在一个线程中,这样就不会阻塞应用程序的其余部分。通过通知观察者更改,他们可以通过执行类似myConnectionWrapper.getMessages()的操作来获取ArrayList;它将返回ArrayList,但同时也会清除ArrayList,如下所示:
public ArrayList getMessages() {
ArrayList temp = arr;
arr.clear();
return temp;
}
这样,您可以获取所有消息并将它们从队列中清除
我以前写过网络客户端,这是其中一个的总体设计。您将有两个线程不断旋转,一个线程发送到接收方消息,另一个线程发送消息
应该使用某种管理器代码来处理逻辑,以确定是继续,还是重新连接,或者执行任何您想执行的操作。谢谢。我同意这个地方不应该成为限制条件,但正是因为我缺乏经验才这样做的如果你能抽出时间举个例子,我会很感激的。谢谢你@Kezzer。实际上,我的包装器类的使用方式与您描述的类似。一个线程使用它读取消息并将它们添加到队列中,另一个线程使用该队列处理输入。但是,我想将所有连接逻辑封装在连接包装器类中。。。。。。套接字(不是流)的
Connected
属性对于此特定问题没有用处。根据MSDN中的文档,它返回上次I/O操作时的连接状态。同一页显示了如何通过发送零字节数组来了解套接字是否已连接。。。。。。最后,“getMessages()”方法将清除返回的数组,因为temp和arr引用同一个对象。可能您的意思是“temp=arr.Clone()”或类似的内容。这取决于您决定如何处理入站消息队列。在我的实现中,我将队列交给主控制器,因此在检索到队列后清除队列实际上是一个逻辑步骤。否则,您如何区分哪些是新的,哪些不是?要区分哪些是新的,哪些不是,我对队列使用volatile
计数,对已使用的消息使用(线程本地)计数。