Здравствуйте, у меня два компьютера соединенные коммутатором. На одном запущена программа-сервер(А), на другом программа-клиент(Б). Между ними средствами сокетов беркли реализован протокол передачи данных такой: читаем первые четыре байта в них заложена длина сообщения(х) в байтах, получаем длину сообщения х+4, далее чтоб записать сообщение заполняем первые 4 байта значением оставшейся длины, записываем. Размеры буферов приема-передачи имеют фиксированный размер(для простоты, максимальный размер сообщения не больше чем размер буфера). Дак вот сначала, и А и В были на одном компе. и через них туда-обратно гонялось по петле по 16 гигов(не всегда программы завершались, иногда блокировались) а как вынес сервер на другой комп. (симулируя реальную сеть), стало приходить-уходить гораздо меньше данных, далее сервер на epoll_wait() ,блокировался. Кстати, сокеты блокируемые, это связано с простотой кода-главное следить за количеством передаваемой информации и все будет хорошо, по крайней мере раньше так думал).
Да, много написал) Но уже битую неделю ищу решение проблемы, а именно: "Что за хрень? через блокируемые сокеты передается известное обоим сторонам количество данных". Но они блокируются то на epoll_wait(), то на read/write, то программа полностью выполняется. Не ожидал я такого поведения, до этого работал с не блокируемыми сокетами с EPOLL (ET), все летало. Сейчас думается может добавить-изменить опции сокетов как на SOL_SOCKET ,так и на IPPROTO_TCP уровнях. Что скажете-посоветуете?
Да, еще добавлю: в некоторых запросах клиента если например в первых 4 байтах содержится -1, сервер не должен отвечать клиенту, вот после таких "однонаправленных" итераций чаще всего глохнет.
Походу придется писать дополнения под циферками:
1) Немного начинаю понимать. Написал прототип программ с искусственными размерами посылаемых сообщений чтоб точно знать где сколько должно прийти-уйти. Алгоритм состоит из 8 итераций, в первой, второй и третьей клиент шлет сообщения только по 4 байта со значением -1, сервет читает -1 при таком значении он не должен отвечать, клиент об этом знает, далее он шлет максимальный размер буфера, сервер читает и отдает также максимальный размер буфера, а далее нет и смысла объяснять) Просто первые три запроса запихались в буфер ядра и отослались серверу целиком, а сервер воспринял как один запрос. Далее пошел полный шлак. Так что не вижу другого выхода, придется читать, кусками сначала константный размер с длиной а потом уже все остальное( А можно по другому?
Почитать учебник Снейдера по TCP/IP.
В частности, то место, где написано, что read (write) может считать меньше байт, чем у нее указано в качестве параметра.
Да я слышал о такой особенности, если "a"=значение первых 4-x, прочитаных байт а "b"-максимальный размер буфера при условии что a<=b; можно вот так "char flags=0;int r, tr=0,a,b=MAX_LEN_BUF;a=b;do{r=read(sd,&mass[tr],a-tr);if(r<=0){закрытие сокета}tr+=r;if(tr>=4 && flags==0){читаем длину;присваиваем это значение a; flags=1;}}while(tr
Данил Тунев, тебе нужно делать два read и два send на компах А и Б соответственно. Первый сенд всегда фиксированной длины, в нем ваше число для сенда второго. Соответственно первый рид длины такой же как и сенд первый, а второй рид переменной длины. Я кстати по данной тематике планирую на хабр статью напечатать
jcmvbkbc, о, на одном оксидосерном сайте на меня недавно набросились, подробно расписывая, что write всегда пишет столько, сколько указано, или блокирует поток.
Данил Тунев, не видя ваш код сложно что-то сказать. Самая распространенная ошибка - отсутствие проверок того, что выдают системные вызовы. Если вы все же удосужитесь почитать учебник, вы там найдете и способ за один системный вызов передать кучу буферов ("запись со сбором") и тактический прием правильного разбора заголовков пакета.
Фокс Йовович, Если бы не следил за возвращаемыми значениями read/write, было бы вообще плохо) Ну да, есть смысл принять максимальное сообщение а потом уже разложить всю логику по полочкам, заманчиво, подумаю)
Фокс Йовович, Тут подумал, конечно вам огромное спасибо, верное решение! но недоверие у меня к книгам зашкаливает, почитал в свое время "воздушных" книг. В принципе, манов достаточно. Код не выложу, по той причине что его много! и не в одном файле, а еще, не хочу чтоб его кто то знал) В вопросе все было понятно