Возникшие вопросы не ограничиваются топиком.
Имеется:
WinSock 1.1, и сокеты работающие в асинхронном режиме. Подписка на события осуществляется через WSAAsyncSelect.
Вопросы:
1. У каждого сокета есть свой буфер отправки, размер которого регулируется setsockopt. Предположим он равен 1К. Тогда каким образом мне удавалось запихнуть гораздо большие объемы за один send? Получается у сокета этих отправных буферо несколько? Или он успевает все отправлять? Скажем, если писать очень большой блок данных, то WSAEWOULDBLOCK не появлялся, а сразу возникал WSAENOBUFS. Я пробовал разбивать массив отправляемых данных на порции, равные размеру отправного буфера. Тогда, если не второй, то третий send возвращал SOCKET_ERROR:WSAEWOULDBLOCK — то есть жди FD_WRITE. Отсуда главный вопрос: КАКИМИ ПОРЦИЯМИ МОЖНО ПИХАТЬ ДАННЫЕ В send?
2. Интересные вопросы возникли и на приеме. Предположим, что отправной буфер на отправной стороне и приемный буфер на приемной стороне имеют объем 256К. Я передаю данные порциями по 256К. Иногда на приемной стороне появляются нормальнве куски размером 128-256К, Но иногда вся порция может быть разбита на мелкие куски по 10К. Я конечно понимаю, что TCP не обязана мне давать данные теми же порциями, что я их и отсылал, но зачем она так мелко дробит эти порции(причем иногда дробит, а иногда не дробит)? Можно ли это как-нибудь победить (или исскуственно принудить), чтобы не обрабатывать вместо одного FD_READ несколько десятков.
3. Почему FD_CONNECT возникает раньше FD_ACCEPT? Причем если не обрабатывать FD_ACCEPT, то все равно приходит FD_ACCEPT без ошибки.
Здравствуйте, Аноним, Вы писали:
А>У каждого сокета есть свой буфер отправки, размер которого регулируется setsockopt. Предположим он равен 1К. Тогда каким образом мне удавалось запихнуть гораздо большие объемы за один send? Получается у сокета этих отправных буферо несколько? Или он успевает все отправлять? Скажем, если писать очень большой блок данных, то WSAEWOULDBLOCK не появлялся, а сразу возникал WSAENOBUFS. Я пробовал разбивать массив отправляемых данных на порции, равные размеру отправного буфера. Тогда, если не второй, то третий send возвращал SOCKET_ERROR:WSAEWOULDBLOCK — то есть жди FD_WRITE. Отсуда главный вопрос: КАКИМИ ПОРЦИЯМИ МОЖНО ПИХАТЬ ДАННЫЕ В send?
Явно не большими чем размер буфера И явно после того как пришел FD_WRITE.
Сокетами давно не пользовался, так что вывод сделан на основе приведенных тобой фактов
К сожалению, в действительности все выглядит иначе, чем на самом деле.
Еще странности:
1. Размер обоих буферов — 8192 Пользуюсь send() и recv() Пишу кусками по 10000, на другой стороне не читаю. Без блокировки записывается 7 кусков, на восьмой блокируется. Можно подумать что 70000 может проглотить, а 80000 уже не может. Но если седьмой кусок не 10000 а 200000, все равно без блокировки, т.е. проглатывает более 200000
2. На одной стороне пишу за раз 200000, на другой читаю. Если сначала записать, а потом пытаться читать, то прочитывается за несколько раз. Если же сначала вызвать recv() а потом уже записать, то все 200000 прочитываются сразу.
Экспериментировал на win2k, два компа в одной подсетке.