Server Async Sockets - Обнаружить закрытое соединение от клиента? - PullRequest
0 голосов
/ 01 марта 2012

У меня есть следующий исходный код с сайта MS: http://msdn.microsoft.com/en-us/library/fx6588te.aspx

Я пытаюсь определить, когда клиент закрыл соединение.

Один из способов, которым я пытался, - это отправлять данные клиенту до тех пор, пока я не получу исключение. Я создал новый поток, который выполняется один раз в onDataReceive, но я получаю сообщение об ошибке «Не удается получить доступ к удаленному объекту»:

m_workerSocket[socket_id].Send(bytes);

но если я вставлю его непосредственно в onDataReceive, он будет работать нормально. Почему я получаю это исключение при попытке получить доступ к сокету из другого потока?

Тогда я нашел второе решение:

static class SocketExtensions
{

    public static bool IsConnected(this Socket socket)
    {
        try
        {
            return !(socket.Poll(1, SelectMode.SelectRead) && socket.Available == 0);
        }
        catch (SocketException) { return false; }
    }
}

Который я тоже хотел запустить в отдельном потоке, чтобы проверять всякий раз, когда сокет закрывается, но я получаю ту же ошибку. Я получаю ошибку только в том случае, если я пытаюсь сделать это из потока, если я помещаю оба решения в одну из функций, они выполняются нормально. Любые идеи, как запустить это из потока?

Ответы [ 3 ]

1 голос
/ 26 февраля 2013

Попробуйте этот код:

public static void ReadCallback(IAsyncResult ar)
{
    String content = String.Empty;

    // Retrieve the state object and the handler socket from the asynchronous state object.
    StateObject state = (StateObject)ar.AsyncState;
    Socket handler = state.workSocket;

    if (handler != null && !handler.Poll(1, SelectMode.SelectRead) && handler.Connected && handler.Available == 0)
    {
        // Read data from the client socket. 
        int bytesRead = handler.EndReceive(ar);
        if (bytesRead > 0)
        {
            // Parsing data received in here..

            // Enabled received for next data
            handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
        }
    }
    else
    {
        if (handler.Connected)
        {
            // Client are offline will be detected here
            IPEndPoint clientIP = handler.RemoteEndPoint as IPEndPoint;
            MessageBox.Show(String.Format("IP Client: {0}:{1} disconnected", clientIP.Address, clientIP.Port));
        }
        {
            // Server are offline will be detected here
        }
    }
}
1 голос
/ 01 марта 2012

Если только проблема заключается в том, чтобы определить, когда клиент отключен: у меня была такая же проблема на моем сокет-сервере, и, наконец, я решил отправить "флаг" отключения от любого клиента на сервер, когда он отключен.

0 голосов
/ 21 сентября 2013

Все, что вам нужно сделать, это правильно обработать вашу функцию выгрузки, чтобы ваши клиенты обнаружили ненормальное закрытие на стороне клиента. Client.connected не очень надежен на стороне сервера, но это должно помочь.

IE ...

protected override void UnloadContent()
    {

        // TODO: Unload any non ContentManager content here            
        if (client != null)
            client.Close(); // I exist so close the connection...

        // I would place a timout on the server side 
        // client.Available as well to drop inactive clients...

        System.Threading.Thread.Sleep(3000); // Force the Client to stay open long enough to communicate a closure...          
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...