ObjectDisposeException при попытке отправить через повторно открытый сокет

  1. Я использую Socket (Socket A = new Socket ...) для отправки / получения.
  2. когда что-то происходит (отключение), я пытаюсь закрыть / удалить старый объект, а затем создать новый сокет (A = новый сокет ...) (тот же хост / порт)
  3. Фаза connect () проходит нормально, удаленный хост видит соединение.
  4. При попытке отправить самый первый байт сразу получаю:

System.ObjectDisposedException: невозможно получить доступ к удаленному объекту. Имя объекта: 'System.Net.Sockets.Socket'. в System.Net.Sockets.Socket.Send (буфер Byte [], смещение Int32, размер Int32, SocketFlags socketFlags, SocketError и errorCode) в System.Net.Sockets.Socket.Send (буфер Byte [], смещение Int32, размер Int32, SocketFlags socketFlags) в System.Net.Sockets.Socket.Send (буфер Byte [])

Любые идеи?

try
{
   CCMSocket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true);
   CCMSocket.Connect(CCMServer, CCMPort);
}

Теперь при работе с сокетом предложение catch перехватывает SocketException и вызывает метод повторного подключения:

try
{
    //Verify the the socket is actually disconnected
    byte[] Empty = new byte[0];
    CCMSocket.Send(Empty);
}
catch (Exception ex)
{
    bool connected = false;
    int reconnectCounter = 0;
    do
    {
        reconnectCounter++;
        Disconnect(); //<-- Just CCMSocket.Disconnect(true) in a try/catch
        if (Connect(CCMServer, CCMPort)) // <-- method given above
        {
            connected = true;
            CCMSocket.Send(LoginData); // this fails
        }
    } while (!connected);    
}

person Squigly    schedule 16.01.2011    source источник
comment
Не могли бы мы взглянуть на ваш код, чтобы увидеть, как вы распоряжаетесь своими объектами.   -  person Stefan H    schedule 16.01.2011
comment
Можете ли вы опубликовать фрагменты кода, похоже, вы используете ту же ссылку   -  person djeeg    schedule 16.01.2011
comment
Вы где-нибудь используете using блок против Socket объекта?   -  person abatishchev    schedule 16.01.2011


Ответы (1)


Попросите ваш метод Connect создать новый сокет и вернуть этот сокет для отправки данных. Что-то вроде:

try
{
   CCMSocket = new Socket();
   CCMSocket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true);
   CCMSocket.Connect(CCMServer, CCMPort);
   return CCMSocket
}

и

do
{
    reconnectCounter++;
    Disconnect(); //<-- Just CCMSocket.Disconnect(true) in a try/catch
    var newSocket = Connect(CCMServer, CCMPort); // <-- method given above
    if (newSocket != null) 
    {
        connected = true;
        newSocket.Send(LoginData); // should work
        CCMSocket = newSocket; // To make sure existing references work
    }
} while (!connected);

Вам также следует серьезно рассмотреть шаблон асинхронного сокета при создании серверных приложений.

person tenor    schedule 16.01.2011