| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Системное программирование и WinAPI > Правильное закрытие сокета - трабл с closesocket() |
| Автор: A1ukard 25.9.2008, 16:41 | ||
| Пишу класс FTPClient. Столкнулся со следующей проблемой. В протоколе FTP для передачи файлов и команд используются различные соединения. Допустим, клиент хочет закачать файл на сервер. После выполнения некоторых команд клиент получает от сервера host:port c которым он (клиент) устанавливает соединение для передачи файла. Затем клиент пишет в соответствующий сокет содержимое файла, закрывает сокет и ждет от сервера сообщение "226 Transfer complete" по каналу для передачи команд. Если обратиться к MSDN, можно выяснить, что closesocket() на самом деле не сразу закрывает соединение. Это в общем-то логично, поскольку какие-то данные могут оставаться в очереди. Ситуация такая: передается небольшой файл (16 байт). Все хорошо, пока клиент не попытается закрыть data-соединение. В действительности оно не закрывается, клиент начинает ждать от сервера сообщение 226, но его нет, тк data-соединение еще открыто, а размер файла серверу неизвестен, то есть он считает, что файл все еще передается. После таймаута в 10 секунд клиент отсоединяется с сообщением об ошибке, тк протокол был нарушен. Я модифицировал закрытие сокета следующим образом:
Тут TCPClient - базовый класс FTPClient. Эффект достигнут, файл успешно передается, протокол не нарушается. Но решение кажется мне грязным. Оно работает на моей машине, но нет гарантии что будет работать у всех пользователей. Функции Sleep и closesocket вобще друг с другом никак не связаны. Скажите, пожалуйста, как правильно дождаться полного закрытия соединения? В MSDN этот вопрос описан весьма туманно, например рекомендуется использовать shutdown, но в действительности мне это не помогло. Есть какой-то вариант с linger structure, но, как я понял, в этом случае есть вероятность, что данные не будут отправлены до конца. Возможно, я что-то упустил, тк английским владею далеко не свободно. Код не могу выложить, поскольку это часть курсового проекта. Да, как я понимаю, проблема широко распространена, например судя по http://community.livejournal.com/csharp_ru/59977.html и тому, что через гугл можно найти много исходников с вызовом sleep после close или closesocket. Зарание спасибо. |
| Автор: A1ukard 25.9.2008, 18:36 |
| упс... ) never mind Винда так или иначе закрывает соединение очень быстро. Моя ошибка была в том, что устанавливал соединение не в тот момент. Я делал это после команды STOR и сервер (Quick'n Easy FTP Server Lite 3.1, в девичестве Pablo's FTP Server) разрешал это, но реагировал указанным выше образом. Другой сервер просто не отвечал на STOR, потому я попробовал устанавливать соединение сразу после PASV и это помогло. |
| Автор: Dem_max 25.9.2008, 19:17 | ||
Юзай
|