ixania
Гость
|
|
« : 22-12-2003 23:29 » |
|
Как известно чтоб задать размер принимаемого или передваемого буфера над вызвать для соответствующего сокета следующее:
int b_sz = 1024
setsockopt (s_socket, SOL_SOCKET, SO_RCVBUF,(char*)&b_sz, sizeof (b_sz));
и
setsockopt (s_socket, SOL_SOCKET, SO_SNDBUF,(char*)&b_sz, sizeof (b_sz));
соответсвенно.
Так вот интересно будет ли в данном случае работать алгоритм Nagle (TCP_NODELAY ), или его над явно вырубать. Проблема в том что над гонять по сетке данные размеров не превышающих максимальной длины и ваще стоит ли искуственно сегментировать свои данные или отдавать в send весь буфер и перебросить все на плечи winsock?
И еще вопросик, стоит ли на серверной стороне для каждого конекта выелять отдельный поток для приема данных. У меня в принципе есть свое мнение по данному вопросу, считаю что нет смысла выделять отдельные потоки для экономии ресурсов темболее на однопроцесорной системе, какая разница что квант времени будет делится между потоками или он достанится одному процессу с более высоким приоритетеом. Конечно в отдельных потоках можно следить за активностью конекта и динамически менять приоритет потока либо отказыватся от оставшейся доли кванта тем-же Sleep (0).
Буду благодарен за любые мнения по данному поводу, думаю что многие сталкиваются с даным родом вопросов от которых зависит архитектура сетевых модулей проектируемой системы.
|
|
|
Записан
|
|
|
|
RXL
|
|
« Ответ #1 : 23-12-2003 09:30 » |
|
Не маловат ли буфер (1024 в твоем примере)? Использование буфера приема меньше чем mtu чревато сбоями и патерями пакетов. Какая цель уменьшения буфера? Какой протокол используешь - tcp, udp или еще какой?
Поток на соединение - этот принцип просто упрощает программирование, а на однопроцессорной системе только снижает производительность (чем больше потоков, тем больше снижает). Зачем использовать Sleep()? - лучше блокироваться в select(), или, коли речь о winsock, использовать WSA.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
ixania
Гость
|
|
« Ответ #2 : 23-12-2003 15:13 » |
|
1024 эт к примеру, использую tcp, уменьшение буфера может потребоватся... дам маленький пример, допустим у нас какойто сервер бизнес логики, ну и вот на станции есть режим обработки списка финансовых транзакций скажем из зарание приготовленого файла, допустим размер данных одной транзакции равен тому же 1024 (прозьба к цифрам не цеплятся эт так для примера) и что получается в цикле мы считываем из файла и посылаем, так вот все хорошо когда этот мту кратен размеру данных транзакции, а если нет то придется усложнить алгоритм приема на стороне сервака т.к. вместо 2-3 отосланых станцией пакетов сервак может получить 1-2 либо 2,5 т.е. кусочек следующего пакета. Так вот ограничение размера упрощает алгоритм.
И чемже блокирующий select() лучше чем Sleep()? Я ваще под форточки блокирующими сокетами не пользуюсь, коряво получается и поток через одно место останавливать надо. У меня это выглядит гдето так:
......... AcceptEvent = WSACreateEvent();
ServerSock = socket (PF_INET, SOCK_STREAM, 0);
bind (ServerSock, ...)
listen (NET4ServerSock, 5)
WSAEventSelect (ServerSock, AcceptEvent, FD_ACCEPT)
while (!ThreadTerminateSignal()){ //
WSANETWORKEVENTS wsaConnectEvent; SOCKADDR_IN sout;
if(WSAWaitForMultipleEvents(1, &AcceptEvent, false, 100, false) == WAIT_OBJECT_0){
WSAEnumNetworkEvents (ServerSock, AcceptEvent, &wsaConnectEvent);
if(wsaConnectEvent.lNetworkEvents & FD_ACCEPT)
if (wsaConnectEvent.iErrorCode[FD_ACCEPT_BIT] == 0) {
SOCKET accept_s = accept (ServerSock, &sout, sizeof (sout)); ................. }
}
} ThreadTerminateSignal() - все что она делает эт проверка мютекса на отсигналеное состояние, этот мютекс используется для отсигналивания завершения всех потоков сервака.
|
|
|
Записан
|
|
|
|
RXL
|
|
« Ответ #3 : 24-12-2003 10:52 » |
|
Как писать дело твое, но я бы не стал крутить буфер, а написал бы ф-ию для чтения _требуемого_ блока. Все же tcp - это поточный протокол - не надо опираться на пакеты, а следует считать его потоком байтов. И чемже блокирующий select() лучше чем Sleep()? После Sleep() поток просыпается, а зачем? После же select() у него есть явное дело. Imho, в winsock реализованы совсем не "BSD sockets", а нечто "свое", похожее... По этому, imho, стоит использовать именно "свои" возможности - WSA - что у тебя в примере и видно. А вот Sleep() что-то не видать... Так в чем же все-таки проблема?
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
ixania
Гость
|
|
« Ответ #4 : 24-12-2003 15:32 » |
|
Прошу заметить что ни о каких проблем я тут не спрашиваю, просто предложил к обсуждению пару моментов на счет которых я не совсем чувствую себя уверенным и хотелось бы услышать все мнения за и против.
А Sleep() я просто не вставил в сообщенеи, он у меня идет в коце while, так что после чего он просыпается опять идет на проверку евента к которому привязан сокет, так что ему определенно есть что делать. То что протокол поточный эт понятно, но разговор не о передачи допустим файла по сетке а определенных пакетов определенной длины так называемых запросов которые порождают так называемые транзакции, так что сервак расматривает именно пакет данных а не весь поток который может содержать несколько пакетов из-за "Наглинга". Хотя он и поточный но размер TCP окна всеже ограничен 64к, а размер МТУ для езернет сети равен (если округлить) 1500. Так вот вопрос если я пошлю одним за другим два пакета допустим по 1550, то сколько пакетов получит сервер два или один? эт при настройках сокета по умолчанию, хотя я и сам возьмусь тестировать это и попоже дам результат теста.
|
|
|
Записан
|
|
|
|
ixania
Гость
|
|
« Ответ #5 : 24-12-2003 15:36 » |
|
2RXL спасибо большое за подержку разговора, на первый взгляд вродь больше критикуешь но на самом деле это очень помогает, насчет того как читать логические блоки я допер, тоесть у меня созрела идея как это реализовать, если комуто будет интересно могу выставить когда закончю.
|
|
|
Записан
|
|
|
|
sss
Специалист
Offline
|
|
« Ответ #6 : 25-12-2003 06:03 » |
|
ixania, давай пообсуждаем немного...
1. стоит ли на серверной стороне для каждого конекта выелять отдельный поток для приема данных... Ты сам ответил - WSAWaitForMultipleEvents может ожидать до 64 подключений. Только вот 100 ms я бы не рекомендовал. Пусть спит на здоровье. Отсюда же не нужен будет и sleep. 2. Как остановить заблокированный поток? shutdown (closesocket) на одном из ожидаемых socket-ов. Например: создать специальный сокет и закрывать его. 3. Зачем mutex? Там одинаково также будет работать простой bool. 4. Причем тут Nagle ?
|
|
|
Записан
|
while (8==8)
|
|
|
RXL
|
|
« Ответ #7 : 25-12-2003 10:22 » |
|
ixania, хорошо когда тебя понимают Был тут спец по сетевым фичам - Olej - жаль что не появляется. Весма интересно почитать его высказывания - если не лень, поройся в старых сообщениях. Напр.: https://forum.shelek.ru/index.php/topic,144.0.html
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
ixania
Гость
|
|
« Ответ #8 : 25-12-2003 12:39 » |
|
Мда парень хорош, можно сказать что прочувствовал протокол. Эт тебе не bind и select что попало и куда попало. Знание библиотечных функции и порядок их использования еще ничего не значит, есть еще кучу мелочей о которых надо знать и учитывать.
|
|
|
Записан
|
|
|
|
|