当前位置: 动力学知识库 > 问答 > 编程问答 >

c# - How should I handle socket disconnections in .NET?

问题描述:

I'm building a (LAN) network application, so there is always the possibility that a connection will be disconnected, for various possible reasons. I am trying to think of a good design for handling this issue, such that it doesn't affect the rest of the application. I wrote a quick thing to try to do it, but I think it can be enhanced a lot. I appreciate your help and experience about the best way to handle this issue.

This is my first trial:

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;

}

}

}

Not very elegant, and probably not the best that can be done. Could you please share your experience, and may be even suggest an existing library?

Thank you.

网友答案:

I honestly don't think you should let the connection wrapper contain logic to handle its own connection policy. I think this should be done from outside of this class, and especially not in the catch statement. Have some kind of ConnectionController object to deal with whether the connection should be retried once it fails.

网友答案:

I was going to edit my post, but this should be completely separate from my last one.

Your logic is all wrong in my opinion, you should have a thread within the ConnectionWrapper which spins on the StreamReader pulling off messages and placing them on a queue. This queue then notifies listeners of a change. The listeners then go and retrieve the data themselves and decide what needs to be done with them.

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);
        }
    }
}

This is pseudo-code I warn you, I've never done this in C#. A typical reader actually waits on a readLine statement, so the while loop won't go crazy. It's also best to put initReceiverThread code in a Thread, that way it won't block the rest of the application. By notifying the observers of a change they can then go and get the ArrayList by doing something like myConnectionWrapper.getMessages(); which will return an ArrayList, but also clearing out the ArrayList at the same time, like so:

public ArrayList getMessages() {
     ArrayList temp = arr;
     arr.clear();
     return temp;
}

That way you get ALL of the messages and clear them off the queue.

I've written network clients before, and this is the general design of one. You'll have two threads constantly spinning, one to receiver messages, and one to send them.

The logic should be dealt with some kind of manager code to determine whether to continue, or reconnect or whatever you want to do.

分享给朋友:
您可能感兴趣的文章:
随机阅读: