LINUX.ORG.RU

[C]Как заставить сообщения приходить немедленно?Почему происходит запаздывание?

 


0

1

Учу сокеты.Есть клиент и сервер,которые связываются через STREAM сокет. Принцип такой:
Сервер ожидает входящих соединений,принимает строку от клиента,затем посылает её всем подключенным клиентам.
После отправки сообщения на сервер,ответ от сервера запаздывает на 3 сообщения,то есть при вводе в терминале клиента получим нечто подобное

Input message:fff
Input message:hhh
Input message:aaa
selectserver: gotmessage from (null) on socket 4, MSG: fff
Input message:sss
selectserver: gotmessage from (null) on socket 4, MSG: hhh
Input message:ggg
selectserver: gotmessage from (null) on socket 4, MSG: aaa
Input message:jjj
selectserver: gotmessage from (null) on socket 4, MSG: sss

Это что,особенности работы сокетов на конкретной системе,или что-то другое?
Исходники:
Сервер
http://codepad.org/x6er1a9p
клиент
http://codepad.org/7W9dGhU1
Форматирование кода немного неудачное,это потому,что там табы вместо пробелов :(

STREAM - значит TCP. TCP - это поток БАЙТОВ, а не сообщений. TCP стек имеет право буферизовать передачу, дожидаться пока будет достаточно данных, чтобы что-то послать.

До определённой степени ты можешь контролировать поведение стека - почитай man tcp на предмет TCP_NODELAY для начала.

deadman ★★
()

> Форматирование кода немного неудачное,это потому,что там табы вместо пробелов :(

Оно неудачное, потому что кто-то намешал и табы и пробелы в одну кучу.

Dendy ★★★★★
()

сообщение может разбиваться на множество кусков, соответственно когда мы посылаем скажем 15 байт при помощи send/write - функция может завершиться сказав что отправила 10 байт - нужно отслеживать это и пропихивать весь пакет до конца, так же и с recv/read

quest ★★★★
()
Ответ на: комментарий от deadman

Хм,всё перепробовал,что только на ум пришло,не помогает. пробовал вызов

setsockopt (sd,SOL_TCP,TCP_NODELAY,&flag,sizeof flag)
и в том числе вперемешку с другими вызовами setsockopt(ибез),а также опции SO_RCVBUF,SO_SNDBUF.Всё вышеперечисленное пробовал ставить на все без исключения сокеты клиента и сервера. Как же быть,какой тут выход? Я уяснил,что есть буферизация на сокетах,но как её отключить,толком пока не понял. ioctl вместе с FIONREAD я тоже пробовал,но единственное,чего удалось сделать,это посылка сервером сообщений по три сразу,также после запаздывания через каждые три,то есть
Input message:fff
Input message:hhh
Input message:aaa
selectserver: gotmessage from (null) on socket 4, MSG: fff
selectserver: gotmessage from (null) on socket 4, MSG: hhh
selectserver: gotmessage from (null) on socket 4, MSG: aaa
...
навроде очистки очереди на сокете. Но саму очередь отключить не удалось. Просветите!

pragmadevel
() автор топика
Ответ на: комментарий от guilder

То есть,получается,без epoll нельзя сделать демо-чат? Цель:чтобы сообщения от клиента мнгновенно приходили серверу(по возможности),а сервер их просто отсылал всем клиентам,причём безо всяких очередей.

pragmadevel
() автор топика
Ответ на: комментарий от pragmadevel

почему нельзя - можно, можно select использовать, можно использовать epoll. Просто насколько я помню epoll использует softwareirq в ядре - да и если вы посмотрите на проекты даже веб серверов - они стараются использовать epoll

guilder
()
Ответ на: комментарий от guilder

Интересно всё же,как в данном случае с select всё это дело провернуть,и почему манипуляции с TCP стеком не работают.

pragmadevel
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.