Malaja
|
|
« : 07-06-2004 15:28 » |
|
Gospoda, pomogite pogalujsta.
Situazija sledujushaja : est neskolko klientow i odin server. ESli neskolko klientow posilajut zaprosi serveru, to pojawljaetsja wisheupomjanutaja oshibka. Ja ponimaju, chto eto sledstwie togo, chto server zanjat obrabotkoj odnogo soobshenija, posemu ne moget rabotat s ostalnimi. Wopros - kak eto isprawit.
|
|
|
Записан
|
холоднокровней, Маня, Ви не на работе --------------------------------------- четкое определение сущности бытия: - А мы в прошлом или в будущем?- спросила Алиса. - Мы в жопе, - ответил кролик. - А "жопа" - это настоящее? - спросила Алиса. - А "жопа" - это у нас символ вечности.
|
|
|
darkelf
Молодой специалист
Offline
|
|
« Ответ #1 : 08-06-2004 05:33 » |
|
сделать сервер многопоточным или многопроцессным. поставить значение побольше в listen(s, backlog). тогда первые backlog клиентов будут становиться в очередь на подключение, а все остальные получать вышепреведенную ошибку.
|
|
|
Записан
|
|
|
|
Malaja
|
|
« Ответ #2 : 08-06-2004 09:58 » |
|
darkelf,
spasibo! Odna prosjba : esli u tebja est horoshij primer i tebja ne zatrudnit - kin mne ego na mail.
Eshe odin wopros :
kak na storone klienta poluchit parametri servera dlja wizowa connect()?
|
|
|
Записан
|
холоднокровней, Маня, Ви не на работе --------------------------------------- четкое определение сущности бытия: - А мы в прошлом или в будущем?- спросила Алиса. - Мы в жопе, - ответил кролик. - А "жопа" - это настоящее? - спросила Алиса. - А "жопа" - это у нас символ вечности.
|
|
|
npak
|
|
« Ответ #3 : 08-06-2004 10:19 » |
|
Malaja, идея в том, чтобы для каждого подсоединившегося клиента создавать отдельную нить, а сокет подсоединения передавать в качестве параметра. В примере ниже обработку запроса клиента осуществляет worker_thread. Пример для Windows, но для линуха переделать не сложно, надо заменить вызов CreateThread на pthread_create DWORD WINAPI worker_thread( LPVOID lpParam ) { SOCKET s = (SOCKET) lpParam;
if ( s == INVALID_SOCKET ) return 1; // // WORK! // return 0; }
int server_main_thread() { // Create socket, bind it, listen to clients while( ( sock = accept ( s, NULL, NULL ) ) != INVALID_SOCKET ) { DWORD dwThreadId; HANDLE hThread;
hThread = CreateThread( NULL, 0, worker_thread, (void *) sock, 0, &dwThreadId ); if ( hThread == NULL) { // TRA TA TA !!! // EXIT } } // close socket, exit }
|
|
« Последнее редактирование: 28-11-2007 17:34 от Алексей1153++ »
|
Записан
|
|
|
|
Malaja
|
|
« Ответ #4 : 09-06-2004 06:28 » |
|
npak, spasibo! Poprobuju sdelat tak, kak ti goworish. Eshe tri malenkih woprosika (srazu izwinjajus, ja eti socketi perwij raz w glaza wigu, posemu i woprosi durnie :oops: ) : 1) kak na storone klienta pered wizowom connect() opredelit port servera? Ja poprobowala tak : struct servent* svr = getservbyname("winpc2", NULL); Resultat : svr = NULL; 2) socket (AF_INET, SOCK_STREAM, 0); Pochemu pri peredache informazii srabatiwaet tolko takaja kombinazia parametrow: send( .... MSG_DONTROUTE); recv(..., MSG_PEEK) ili eto tolko sowpadenie? I gde togda logika pri ih primenenii? Wo wseh knigkah oni tolko opisani, prichem wse wremja kak-to po-raznomu, ja uge okonchatelno zaputalas. 3) Na storone servera pri prieme paketa s pomoshju accept() sozdaetsja nowij handle dlja etogo paketa socketNew = accept(socketSvr, ...); Pri wizowe recv() dlja etogo paketa mi primenjaem etot nowij handle, t.e. recv(socketNew, ... ). A kakoj handle primenjaem dlja otprawki otweta klientu, prislawshemu etot paket - socketNew ili socketSvr? W razlichnih knigkah i primerah po-raznomu, u menja srabatiwaet tolko socketNew, chto s moej tochki zrenija logichno, no wot naskolko eto werno ili eto tolko sowpadenie?
|
|
|
Записан
|
холоднокровней, Маня, Ви не на работе --------------------------------------- четкое определение сущности бытия: - А мы в прошлом или в будущем?- спросила Алиса. - Мы в жопе, - ответил кролик. - А "жопа" - это настоящее? - спросила Алиса. - А "жопа" - это у нас символ вечности.
|
|
|
npak
|
|
« Ответ #5 : 09-06-2004 10:36 » |
|
Malaja, на сайте есть статьи про Winsock, там более-менее подробно разбираются сокеты.
Ответы на твои вопросы.
1. Клиент не может узнать настройки сервера в run-time. Считается, что клиент и сервер заранее договорились о том, какой порт использовать. Например, для http серверов по-умолчанию используется порт 80. Так сложилось. Для некоторых протоколов есть исторически сложившиеся и документально установленные номера портов: http 80, telnet 23, и т.д.
Я обычно выбираю порт больше 20000, и ещё ни разу не сталкивался с проблемами совпадения портов для разных приложений.
2. Для потоковых сокетов надо сначала установить соединение вызовом connect, после установления соединения send должен работать нормально без дополнительных флагов.
3. На стороне сервера accept не получает пакеты. accept принимает входящие запросы на соединение и создает сокеты, по которым будет идти обмен данными.
Сервер создает сокет, привязывает его к некоторому порту и адресу, настраивает на ожидание входящих соединений и принимается ждать подсоединений. На этом сокете, вообще говоря, данные не получаются и не отправляются. Его единственное назначение -- ждать запросы.
|
|
|
Записан
|
|
|
|
npak
|
|
« Ответ #6 : 09-06-2004 10:58 » |
|
Malaja, пример сервера, который на все соединения отсылает строку "Hello, world!" #include <winsock2.h> #include <windows.h> #include <stdio.h>
#define HELLO_MSG "Hello, world!\n"
DWORD WINAPI worker_thread( LPVOID lpParam ) { SOCKET s = (SOCKET) lpParam;
if ( s == INVALID_SOCKET ) return 1; send( s, HELLO_MSG, sizeof( HELLO_MSG ), 0 ); return 0; }
int server_main_thread() { SOCKET s = socket( AF_INET, SOCK_STREAM, 0 ); SOCKET sock; struct sockaddr_in saddr; // Create socket, bind it, listen to clients if ( s == INVALID_SOCKET ) { int error = WSAGetLastError(); return error; }
memset( &saddr, 0, sizeof( saddr ) );
saddr.sin_family = AF_INET; saddr.sin_addr.s_addr = htonl( INADDR_ANY ); saddr.sin_port = htons( 20001 );
if ( bind( s, (struct sockaddr *)&saddr, sizeof(saddr) ) ) { int error = WSAGetLastError(); closesocket( s ); return error; } if ( listen( s, 5 ) ) { int error = WSAGetLastError(); closesocket( s ); return error; } while( ( sock = accept ( s, NULL, NULL ) ) != INVALID_SOCKET ) { DWORD dwThreadId; HANDLE hThread;
hThread = CreateThread( NULL, 0, worker_thread, (void *) sock, 0, &dwThreadId ); if ( hThread == NULL) { closesocket( sock ); // TRA TA TA !!! // EXIT } } closesocket( s ); return 0; }
int main() { WSADATA wsadata; int result; if ( WSAStartup( MAKEWORD( 1, 0 ), &wsadata ) ) { return -1; } result = server_main_thread(); if (result) { fprintf( stderr, "Return error in server %d\n" ); } return result; }
|
|
« Последнее редактирование: 28-11-2007 18:09 от Алексей1153++ »
|
Записан
|
|
|
|
npak
|
|
« Ответ #7 : 09-06-2004 11:26 » |
|
Malaja, пример клиента, который подсоединяется к порту 20001 и распечатывает на стандартный вывод полученную строку. #include <winsock2.h> #include <windows.h> #include <stdio.h>
// Single threaded client
int client_main_thread() { SOCKET s = socket( AF_INET, SOCK_STREAM, 0 ); struct sockaddr_in saddr; char reply_buf[1024]; char * c = reply_buf; // Create socket, bind it, listen to clients if ( s == INVALID_SOCKET ) { int error = WSAGetLastError(); return error; }
memset( &saddr, 0, sizeof( saddr ) ); saddr.sin_family = AF_INET; saddr.sin_addr.s_addr = htonl( INADDR_LOOPBACK ); saddr.sin_port = htons( 20001 );
if ( connect( s, (struct sockaddr *)&saddr, sizeof(saddr) ) ) { int error = WSAGetLastError(); closesocket( s ); return error; }
// receive hello message from server // receive it char by char do { if ( SOCKET_ERROR == recv( s, c, sizeof( *c ), 0 ) ) { int error = WSAGetLastError(); closesocket( s ); return error; } } while ( *c++ );
puts( reply_buf ); closesocket( s ); return 0; }
int main() { WSADATA wsadata; int result; if ( WSAStartup( MAKEWORD( 1, 0 ), &wsadata ) ) { return -1; } result = client_main_thread(); if (result) { fprintf( stderr, "Return error in client %d\n" ); } return result; }
|
|
« Последнее редактирование: 28-11-2007 18:11 от Алексей1153++ »
|
Записан
|
|
|
|
Malaja
|
|
« Ответ #8 : 14-06-2004 12:11 » |
|
npak,
spasibo za primer. No tut woznikaet eshe odin wopros - mne nado, chtonbi wse proishodilo po sledujushej sheme : client posilaet infu, server ee shitiwaet, obrabatiwaet i zatem posilaet otwet clientu, a client ee shitiwaet i toge obrabatiwaet. I eto neskolko raz podrjad, t.e na storone clienta : send - receive, send - receive, ... po mere neobhodimosti
na storone servera : receive - send, receive - send, ... po mere pojawlenija zaprosow otklientow
Tak wot w twoem primere client zawisaet na recv posle prochtenija poslednego simwola peredannoj stroki. Ja peredelala primer po opisannoj mnoju wishe sheme(t.e. obe storoni posilajut i peredajut soobshenija) i poluchaetsja, chto teper obe storoni stradajut ot etogo zawisanija.
Ja poprobowala delat recv ne pobukwenno, a zelikom, posemu ispolzowala w send(..., MSG_DONTROUTE) i recv(..., MSG_PEEK). Pri etom server poluchaet tolko perwoe soobshenie, a wse ostalnie send () ot clienta ne widit.
Posemu wopros - chto i kak nado izmenit, chtobi srabatiwala neobhodimaja mne shema obshenija client-server? Zaranee spasibo.
|
|
|
Записан
|
холоднокровней, Маня, Ви не на работе --------------------------------------- четкое определение сущности бытия: - А мы в прошлом или в будущем?- спросила Алиса. - Мы в жопе, - ответил кролик. - А "жопа" - это настоящее? - спросила Алиса. - А "жопа" - это у нас символ вечности.
|
|
|
npak
|
|
« Ответ #9 : 15-06-2004 12:02 » |
|
Malaja, проблема с recv вызвана флагом MSG_PEEK При таком запросе recv оставляет данные в очереди на получение. MSG_PEEK флаг используется, как правило, для определения количества данных в очереди -- сколько памяти нужно отвести для получения данных. Два последовательных вызова recv c MSG_PEEK будут возвращать одни и теже данные, и, следовательно, до последующих данных дело не дойдёт. По адресу http://www.ispras.ru/~npak/malaya/client_server.zip я выложил пример клинте-серверного приложения, в котором клиент посылает серверу два числа, а сервер возвращает их сумму. Файлы protocol.h и protocol.c предоставляют интерфейс обмена сообщениями. Протокол -- каждое сообщение имеет тип, длину данных и собственно данные. Оправитель посылает данные через функцию send_message, получатель получает данные через receive_message. Для данного приложения (сложение двух чисел) есть три вида сообщений: - сообщение, в котором передаются данные для сложения - сообщение, в котором передаётся результат сложения - сообщение об ошибке (если возникнет) Эти константы и формат сообщений задаётся в service.h Реализация сервера и клинта в server.c и client.c соответственно. И клиет и сервер должны быть скомпилированы с protocol.c Я проверил на Windows 2000 работает. Для компиляции на Линуксе надо будет немного подкрутить (определить SOCKET, INVALID_SOCKET, SOCKET_ERROR и closesocket, а также запуск нити в server.c). Приложение собрано, что называется, "на коленке", за качество ответственности не несу Пока писал сообщение, нашёл несколько потенциальных проблем. Если надо, могу их подправить и сделать более надёжный и читабельный пример.
|
|
|
Записан
|
|
|
|
Malaja
|
|
« Ответ #10 : 15-06-2004 15:10 » |
|
npak, ogromnoe spasibochki ! Primer zagruzila, teper smotrju. Ja pitalas i bez MSG_PEEK delat, no u menja wse rawno ne rabotalo - teper hot mogu ponjat, chto bilo newerno. Приложение собрано, что называется, "на коленке", Пока писал сообщение, нашёл несколько потенциальных проблем. Если надо, могу их подправить и сделать более надёжный и читабельный пример
Esli twoja kolenka eshe ne ustala, podpraw eti problemki, t.k. ja ih sama ne uwigu (w swjazi s neznaniem predmeta) Zaranee bolshushee spasibo!
|
|
|
Записан
|
холоднокровней, Маня, Ви не на работе --------------------------------------- четкое определение сущности бытия: - А мы в прошлом или в будущем?- спросила Алиса. - Мы в жопе, - ответил кролик. - А "жопа" - это настоящее? - спросила Алиса. - А "жопа" - это у нас символ вечности.
|
|
|
Malaja
|
|
« Ответ #11 : 15-06-2004 15:47 » |
|
npak, izwini, dwa (tolko!!!) woprosa - pochemu ti wsjudu primenjaesh funkzii perewoda htonl i ntohl? eto wsegda neobhodimo? - pochemu na storone servera : saddr.sin_addr.s_addr = htonl( INADDR_ANY ); a na storone clienta : saddr.sin_addr.s_addr = htonl( INADDR_LOOPBACK ); t.e. mogno li i na storone clienta ispolzowat INADDR_ANY ili kak?
|
|
|
Записан
|
холоднокровней, Маня, Ви не на работе --------------------------------------- четкое определение сущности бытия: - А мы в прошлом или в будущем?- спросила Алиса. - Мы в жопе, - ответил кролик. - А "жопа" - это настоящее? - спросила Алиса. - А "жопа" - это у нас символ вечности.
|
|
|
darkelf
Молодой специалист
Offline
|
|
« Ответ #12 : 16-06-2004 05:22 » |
|
1) желательно всегда, потому что network byte order в i86 отличается от host byte order. не переводить, помоему, можно на SPARC-процессорах и некоторых других. 2) сервер принимает запросы с любых интерфейсов. расчитывается, что клиент запускается на той-же машине На стороне клиента необходимо указывать ip-адрес сервера, INADDR_ANY для этих целей не подходит, насколько я знаю.
|
|
|
Записан
|
|
|
|
Malaja
|
|
« Ответ #13 : 16-06-2004 07:37 » |
|
darkelf, spasibo. No tut situazija : neuchenje - tjma, a uchenie - sploshnaja tjma Ja pokopalas w dokah i teper sowsem zaputalas w parametrah tipa INADDR_ANY i INADDR_LOOPBACK. Na storone klienta po wozmognosti dolgen bit woobshe ukazan tochnij port, a wot chto proizojdet, esli ukazat INADDR_LOOPBACK , a server i klient nahodjatsja na razlichnih mashinah? I srabotaet li INADDR_ANY, ukazannoe na storone servera, w etoj situazii? Wsjudu stoit, chto INADDR_ANY podhodit dlja situazii, pri kotoroj server i klient nahodjatsja na odnoj mashine. Koroche, sowsem ja zaputalas, prostite, no bez washej pomoshi nikak! :oops:
|
|
|
Записан
|
холоднокровней, Маня, Ви не на работе --------------------------------------- четкое определение сущности бытия: - А мы в прошлом или в будущем?- спросила Алиса. - Мы в жопе, - ответил кролик. - А "жопа" - это настоящее? - спросила Алиса. - А "жопа" - это у нас символ вечности.
|
|
|
npak
|
|
« Ответ #14 : 16-06-2004 09:52 » |
|
npak, izwini, dwa (tolko!!!) woprosa - pochemu ti wsjudu primenjaesh funkzii perewoda htonl i ntohl? eto wsegda neobhodimo? - pochemu na storone servera : saddr.sin_addr.s_addr = htonl( INADDR_ANY ); a na storone clienta : saddr.sin_addr.s_addr = htonl( INADDR_LOOPBACK ); t.e. mogno li i na storone clienta ispolzowat INADDR_ANY ili kak? Два -- это хорошо Я их уже давно ждал 1. Про htonl и ntohl ( а так же ntohs и htons ). На разных процессорах многобайтовые числа могут задаваться по-разному. Например, четырёхбайтовое число 0x01 на интеле будет представлено такой последовательнстью байт: 0x01 0x00 0x00 0x00 На спарке это же число будет 0x00 0x00 0x00 0x01 Классики рекомендуют числа по сети передавать в некотором каноническом виде, соответственно отправитель должен числа к этому виду приводить, а получатель из него преобразовывать. В принципе, если у тебя и клиент, и сервер работают на однотипных процессорах, то это преобразование можно не делать. Или можно выбрать свой способ передачи данных в виде потока байтов, и восстановления данных из потока обратно. 2. Если ты привяжешь сокет сервера к некоторому фиксированному адресу, то этот сервер будет слушать запросы на соединение только на указанный адрес. Каждый компьютер, подсоединённый к интернету, имеет как мининмум два адреса -- один на сетевой карте и 127.0.0.1 (так называемый "псевдоинтерфейс петля"). Адрес INADDR_ANY по соглашению не может быть присвоен никакому сетевому устройству. Поэтому привязывание к этому адресу интерпретируют, что сокет принимает все запросы на данный порт, вне зависимости от адреса. В клиенте запрос на соединение с адресом INADDR_ANY будет отвергнут, так как в интернете нет компьютера с таким адресом. Надо указывать конкретный адрес. Я в примере использовал адрес INADDR_LOOPBACK (127.0.0.1), в предположении, что сервер работает на одной машине с клиентом. Более того, если сервер должен принимать соединения только от локальных клиентов, то следует сокет сервера тоже привязывать к INADDR_LOOPBACK, так лучше для секьюрити. В таком случае все запросы извне на порт сервера будут отклоняться, так как порт слушает локальный адрес. И злобные хацкеры-крякеры не смогут своими шаловливыми ручёнками в сервере поковыряться.
|
|
|
Записан
|
|
|
|
Anonymous
Гость
|
|
« Ответ #15 : 16-06-2004 12:39 » |
|
npak, spasibo za terpenie! No u menja opjat woprosi ! :oops: 1) s htonl и ntohl teper ponjatno! No : est wed eshe i parochka htons - ntohs ! Esli string toge peredaetsja w wide potoka bayt, prichem ascii-kod kagdoj bukwi moget bit perewernut analogichno obichnim zifram, to eto preobrazowanie neobhodimo. Esli ge prinzip peredachi strings drugoj, to eto neobjazatelno. Sootwetstwenno wopros - nado ih primenjat ili net ? 2) po powodu INADDR_ANY : poluchaetsja, chto w servere etu konstantu mogno primenjat dage w tom sluchae, esli client i server sidjat na raznih mashinah? Delo w tom, chto prilogenie dolgno bit uniwersalnim, t.e. rabotat kak na odnoj mashine, tak i na raznih. Posemu INADDR_LOOPBACK zdes menja ne spaset.
|
|
|
Записан
|
|
|
|
RXL
|
|
« Ответ #16 : 16-06-2004 12:51 » |
|
1) htonl() и ntohl() работают с unsigned long int. htons() и ntohs() работают с unsigned short int. Строки - они и в африке строки, т.е последовательность байт и конвертить их не надо.
2) INADDR_ANY = 0x00000000 = IP 0.0.0.0 Т.е., bind() на этот адрес означает "подключить сокет ко всем сетевым интерфейсам".
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
npak
|
|
« Ответ #17 : 16-06-2004 16:35 » |
|
Malaja, проблема в том, что на разных процессорах многобайтовые числа кодируются разными порядками байт. Но значения отдельных байтов не меняются.
В строке байт -- он один, его не перевернуть.
|
|
|
Записан
|
|
|
|
Malaja
|
|
« Ответ #18 : 17-06-2004 06:23 » |
|
npak, ponjatno, spasibo, teper ponjala. No teper ja zadalas eshe odnim woprosom :oops: - moget, est smisl pri multithreadinge ispolzowat neblokirujushie soketi? Ili eto bessmislenno? I esli da - to kak? I eshe : odna malenkaja prosjba - esli ti swoj primer podkorrektiruesh, skagi - ja ego opjat zaberu.
|
|
|
Записан
|
холоднокровней, Маня, Ви не на работе --------------------------------------- четкое определение сущности бытия: - А мы в прошлом или в будущем?- спросила Алиса. - Мы в жопе, - ответил кролик. - А "жопа" - это настоящее? - спросила Алиса. - А "жопа" - это у нас символ вечности.
|
|
|
npak
|
|
« Ответ #19 : 17-06-2004 06:58 » |
|
Malaja, использовать блокирующие сокеты или нет -- на это надо ответить "а зачем?" Неблокирующие сокеты стоит использовать, когда одна нить будет обрабатывать несколько запросов. Поработала с одним сокетом, затем с другим, и так далее. Для многих задач достаточно пользоваться блокируюшими сокетами. Если надо неблокирующий сокет, то после создания сокета надо перевести его в неблокирующее состояние. В винде это делается функцией ioctlsocket //------------------------- // Set the socket I/O mode: In this case FIONBIO // enables or disables the blocking mode for the // socket based on the numerical value of iMode. // If iMode = 0, blocking is enabled; // If iMode != 0, non-blocking mode is enabled. int iMode = 0; ioctlsocket(m_socket, FIONBIO, (u_long FAR*) &iMode);
|
|
« Последнее редактирование: 28-11-2007 18:11 от Алексей1153++ »
|
Записан
|
|
|
|
Anonymous
Гость
|
|
« Ответ #20 : 17-06-2004 11:59 » |
|
npak,
spasibo za objasnenie! sudja po wsemu eto, wo-perwih, ne ochen nadegno, a wo-wtorih, redko primenjaetsja.
|
|
|
Записан
|
|
|
|
npak
|
|
« Ответ #21 : 17-06-2004 12:05 » |
|
Гость, Малая -- это ты?
Неблокирующиеся сокеты -- это теже самые сокеты, только функции не ждут результатов, а отваливаются сразу. Есть такое наблюдение -- асинхронный код писать и отлаживать всегда сложнее, чем синхронный. Поэтому я неблокирующимся сокетом пользовался всего раза два, обычно вполне хватало блокирующихся.
|
|
|
Записан
|
|
|
|
Malaja
|
|
« Ответ #22 : 17-06-2004 12:15 » |
|
npak, eto ja, izwini, ja ne uwidela, chto menja opjat ne ljubjat i wikinuli iz spiska spasibo za objasnenie, ja ponjala. Odna prosjba - esli u tebja est primer asinhronnogo soketa, wilogi kak uchebnoe posobie ( wse-taki interesno, kak eto dolgno bit organizowano :oops: )
|
|
|
Записан
|
холоднокровней, Маня, Ви не на работе --------------------------------------- четкое определение сущности бытия: - А мы в прошлом или в будущем?- спросила Алиса. - Мы в жопе, - ответил кролик. - А "жопа" - это настоящее? - спросила Алиса. - А "жопа" - это у нас символ вечности.
|
|
|
darkelf
Молодой специалист
Offline
|
|
« Ответ #23 : 17-06-2004 15:36 » |
|
в принципе, все выглядит также, как и блокируемыми сокетами, только в неблокирующем режиме может возвращаться EAGAIN/EWOULDBLOCK (в Windows WSAEWOULDBLOCK), что означает, что операцию надо повторить через некоторое время. также функции send() может возвращать, что количество выданных данных меньше запрошенного, и те данные, которые не выданы необходимо довыдавать. Если можете - постарайтесь достать книгу Ричарда У. Стивенса "UNIX: Разработка сетевых приложений", почти все, что там написано, вполне подходит и для Windows.
|
|
|
Записан
|
|
|
|
Malaja
|
|
« Ответ #24 : 18-06-2004 14:55 » |
|
darkelf, spasibo za objasnenie, popitajus najti etu knigu. Tut eshe odin woprosik nazrel : nado li pered recv wiziwat setsockopt s parametrom SO_RCVBUF, osobenno esli rech idet ob ochen bolshom kolichestwe chars? Spasibo zaranee.
|
|
|
Записан
|
холоднокровней, Маня, Ви не на работе --------------------------------------- четкое определение сущности бытия: - А мы в прошлом или в будущем?- спросила Алиса. - Мы в жопе, - ответил кролик. - А "жопа" - это настоящее? - спросила Алиса. - А "жопа" - это у нас символ вечности.
|
|
|
npak
|
|
« Ответ #25 : 18-06-2004 15:37 » |
|
Malaja, нет, не надо
TCP должен сам справиться с передачей данных
|
|
|
Записан
|
|
|
|
Malaja
|
|
« Ответ #26 : 25-06-2004 08:09 » |
|
npak, izwini, ne otwetila wowremja - prosto menja tut tremja proektami na c i vb odnowremenno zabili pochti nasmert :twisted: no ja wigila Po powodu bufera : poluchaetsja tak - esli razmer bufera, ustanowlennij po umolchaniju kak SO_MAX_MSG_SIZE (okolo 8200 bytes) , dostatochen, to nichego ne nado. Esli ge bufer dolgen bit bolshe (u mneja , naprimer, 22000 bytes), to etot razmer nado zadawat s pomoshju setsockopt(s, ... SO_RCVBUF...), inache resv zawisaet. Moget, ja chto-to eshe dolgna sdelat, chtobi socket sam umnim stal bez moej podskazki w wide setsockopt ?
|
|
|
Записан
|
холоднокровней, Маня, Ви не на работе --------------------------------------- четкое определение сущности бытия: - А мы в прошлом или в будущем?- спросила Алиса. - Мы в жопе, - ответил кролик. - А "жопа" - это настоящее? - спросила Алиса. - А "жопа" - это у нас символ вечности.
|
|
|
npak
|
|
« Ответ #27 : 25-06-2004 10:43 » |
|
Malaja, я сделал примерчик, в нём нормально отсылаются 30 000 байт и нормально принимаются.
В теории это устроено так: отправитель шлёт данные небольшими кусками, для отправки последующего надо получить разрешение от получателя. Если в получателе буфер забит, то получатель не разрешает высылать последующие данные до тех пор, пока не появится свободное место. Вызов recv перекачивает данные из внутренних буферов в буфер программы, тем самым освобождая место, необходимое для складирования следующих данных.
Таким образом, если в сокетах TCP ничего не крутить, то всё будет работать само собой. Обновлённый пример лежит на прежнем месте.
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #28 : 22-01-2009 12:56 » |
|
не по теме но близко... настраиваю NAS сервер Sinology (маленькая такая коробочка) пытаюсь оживить FTP. в локальной сети вроде видиться - во внешней при попытки зайти через FAR - выдается та же ошибка) вопрос: это я не все порты на точке доступа отмапировал? (20/21 вроде открыл) или еще что надо? или другая проблемма? хотя бы на мысль наведите) сколько портов для FTP надо? и для SSL/TSL FTP?
дурной вопрос, но я не в зуб ногой в сетевых задачах)
|
|
« Последнее редактирование: 22-01-2009 12:57 от Ochkarik »
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
Sla
|
|
« Ответ #29 : 22-01-2009 13:08 » |
|
Ochkarik, в зависимости от ftp пассивный или активный
|
|
|
Записан
|
Мы все учились понемногу... Чему-нибудь и как-нибудь.
|
|
|
|