Получить все данные, если соединение было закрыто раньше

У меня есть клиент, который подключается к серверу, начинает отправлять двоичные данные, а когда отправка завершена, он закрывает соединение. Если соединение закрыто, сервер знает, что клиент отправил файл.

У меня есть простой класс TCP для обработки соединения. Затем у меня есть еще одна функция, которая отправляет данные на сервер:

  TcpC tcp = new TcpC();

  void send_data_to_server(){
        tcp.connect();

        while(read_data){
            tcp.sendData();
        }

        Thread.Sleep(500);
        tcp.disconnect();
  }

Сервер использует асинхронные сокеты и имеет функцию WaitForData(), которая получает исключение, когда клиент отключается. Проблема в том, что если я удалю Thread.Sleep(), WaitForData все еще перехватывает исключение, но onDataReceive все еще не получил все данные, потому что я проверяю размер буфера в исключении, и он намного меньше, чем если бы я использовал Sleep().

Серверу придется обрабатывать множество подобных операций, и я не могу позволить себе использовать «хак» Sleep(), чтобы он работал. Иногда это все равно не работает, и я должен установить интервал сна на пару секунд, чтобы быть уверенным. Ни одна из других асинхронных функций на стороне сервера не вызывает исключение, кроме WaitForData().

Как я могу немедленно закрыть соединение и при этом получить все данные? Хотя tcp.disconnect все равно вызывается после отправки всех данных, поэтому я не понимаю, почему у меня возникла эта проблема. Спасибо!


person user1015551    schedule 18.03.2012    source источник


Ответы (1)


Из документов MSDN:

Чтобы убедиться, что все данные отправлены и получены до закрытия сокета, перед вызовом метода Disconnect следует вызвать Shutdown.

Возможно, стоит попробовать.

В противном случае, если ваш фрагмент кода является каким-либо указанием (на основе вашего использования TcpC), вам, вероятно, следует использовать TcpClient.Close, который, как я полагаю, сделает это за вас.

person M.Babcock    schedule 18.03.2012
comment
Еще раз спасибо! Как ни странно, использование выключения не приводит к срабатыванию каких-либо исключений на стороне сервера, но я могу определить, закрыто ли соединение, проверив количество входящих данных onDataReceived, так что ничего страшного. - person user1015551; 18.03.2012
comment
Раньше я использовал TcpClient.Close(). Выключение решило мою проблему, спасибо! - person user1015551; 18.03.2012
comment
В дополнение к полузакрытому отключению, если вы хотите быть абсолютно уверены, что клиент получил данные, которые вы намеревались отправить, вы должны дождаться, пока клиент сначала отключится (с разумным временем ожидания), прежде чем формально закрывать сокет. - person selbie; 18.03.2012