C++ Windows IOCP - отсутствуют данные HTTP POST
Я написал очень простой HTTP-сервер IOCP, который работает для глагола GET, но не POST.
Я создаю сокет и поток прослушивания, в котором accept() ожидает соединения. Когда клиент подключается, я вызываю ioctlsocket(), чтобы разблокировать сокет, затем связываю сокет с IOCP и, наконец, вызываю WSARecv() для чтения данных.
Некоторые данные действительно читаются, и когда это происходит, IOCP запускает рабочий поток через GetQueuedCompletionStatus(), и я восстанавливаю данные запроса.
Я получаю заголовок запроса только когда отправляю сообщение из любого браузера. Любые предложения о том, почему?
1 ответ
Все операции чтения на сокете TCP будут возвращаться в любом месте от 1 байта до общего объема, отправленного в зависимости от размера буфера, который вы предоставляете. Вероятно, происходит то, что веб-сервер отправляет данные в виде двух отдельных записей, и это происходит из-за того, что стек TCP сервера передается в виде двух отдельных блоков данных. Ваше чтение завершено, потому что данные поступили. Чтение не ожидает до тех пор, пока все данные, ожидаемые вами, программист, не поступят или даже до тех пор, пока ваш буфер не заполнится.
Проблемы с сетью могут еще больше запутать ситуацию, так как маршрутизаторы могут фрагментировать объекты, а потерянные данные могут задерживать их, пока они отправляются повторно.
Всегда при работе с TCP вы должны предполагать, что ваши чтения всегда будут возвращать только один байт за раз и код соответственно; таким образом, вещи всегда будут работать.
Вам нужно просто выполнить еще одно чтение, и вы получите остальные данные, когда они поступят.
Возможно, вы захотите взглянуть на мою бесплатную платформу IOCP-сервера (она также работает с клиентами), которую можно найти здесь; Похоже, у вас уже есть что-то работающее, но иногда помогает взглянуть на что-то другое.
Когда мне нужно накапливать данные перед обработкой, я склонен придерживаться следующего подхода. Выполните чтение и дождитесь его завершения, посмотрите, что у меня есть, и, если у меня нет всего, что мне нужно, и в моем буфере все еще есть место, отрегулируйте WSABUF
я использую его так, чтобы он указывал на конец текущих данных, которые только что поступили в тот же буфер, и выполнил еще одно чтение; затем мы накапливаемся в том же буфере, пока либо у меня не будет достаточно данных для обработки, либо мне нужно добавить еще один буфер, чтобы получить еще немного.