IceStudent А ты подумай, если одновременно всё клиенты чтото захотят - что тогда - один поток загнеться, хотя я не говорю что много потоков - ето хорошо, просто хочу знать вашые мнения - как лутче всего держать много сойдинений? Если не тежело - небольшой пример - как работать с select, тоесть тока самое главное (ненада создание сокета и его бинд - тока как с селект работать) Зарание благодарен
Примерно вот так Одинаково что для Unix что для Win машин BSD сокеты везде совместемы единственное отличие первый параметр select сделан для совместимости в WIN Код (Text): XS5RetCode XS5ServerLoop( SOCKET serverSocket, PXS5SOCKSOPT pXS5SockOpt ) { int fd; fd_set array; struct timeval tv; SOCKET clientSocket; while( pXS5SockOpt != NULL ) { FD_ZERO( &array ); FD_SET( serverSocket, &array ); tv.tv_sec = pXS5SockOpt->uiAceptTimeout; tv.tv_usec = 0; fd = select( serverSocket + 1, &array, NULL, NULL, &tv ); if( fd ) { if( XS5ServerAccept( serverSocket, &clientSocket) != -1 ) { #ifdef WIN32 DWORD dwThreadId; #endif XS5COREPARAM xS5CoreParam; xS5CoreParam.clientSocket = clientSocket; #ifdef WIN32 CreateThread( NULL, 0, XS5CoreThread, (LPVOID)&xS5CoreParam, 0, &dwThreadId); #endif } } } return XSOCKS_SUCCESS; } чтение из сокетов Код (Text): XS5RetCode XS5CoreTcpData( SOCKET clnSocket, SOCKET appSocket ) { int fd; fd_set arrayFd; struct timeval tv; int iCountRecv = 0; char szMessage[1024] = {0}; while(1) { FD_ZERO( &arrayFd ); FD_SET( clnSocket, &arrayFd ); FD_SET( appSocket, &arrayFd); tv.tv_sec = 1800; tv.tv_usec = 0; fd = select(appSocket + clnSocket + 1, &arrayFd, NULL, NULL, &tv); if( fd ) { if( FD_ISSET( clnSocket, &arrayFd ) ) { memset(szMessage, 0, sizeof( szMessage ) ); if( (iCountRecv = recv(clnSocket, szMessage, sizeof(szMessage), 0)) != SOCKET_ERROR ) { if( iCountRecv > 0 && send( appSocket, szMessage, iCountRecv, 0 ) != SOCKET_ERROR ) { continue; } } break; } else if( FD_ISSET( appSocket, &arrayFd ) ) { memset(szMessage, 0, sizeof( szMessage ) ); if( (iCountRecv = recv(appSocket, szMessage, sizeof(szMessage), 0)) != SOCKET_ERROR ) { if( iCountRecv > 0 && send( clnSocket, szMessage, iCountRecv, 0 ) != SOCKET_ERROR ) { continue; } } break; } } } }
IceStudent Вы хоть и модератор, но говорите чушь. Работа с select сводиться к прогонке массива битовых флагов, если у вас будет более 10к, то такой сервер работать не будет. Тем более 200к соед. спрашивается сколько длиться работа с каждым клиентом? Немного. Этот механизм устарел давно. Не зря для FreeBSD реализовали kqueue, для линокса epool а для windows nt iocp. разве, что можете сказать, что стебаетесь нтаким образом с топикстартера
Cock Но-но, апач стал использовать многопоточность только со второй версии, как же он справлялся с соединениями до этого?
Смотрим исходники апача, что такое префорк(аналог thread pool), заметим также, что в этих системах графика вынесена из ядра, сколько ресурсов освободженно. И к тому же апач никогда не держал и не может держать такое количество соеденений. И заметим, что процесс, для мира уних, это сущность другая, чем у виндовс. К тому же где есть cgi этому тоже не бывать, смотрим fastcgi, смотрим модули к апачу. Вообще не хотел тебя обидеть, если уж сказал апача - рекомендую посетить сайт http://apachedev.ru.
Cock Можна немного подробнее о nt iocp? так как хочу подробно изучить всё аспекты и выбрать найлутчшый путь. Еще один небольшой вопрос - я создал небольшую прогу - которая создает сервер и потом конектить много клиентов, но оказалось что я могу законектить тока приблизительно 4000, но почему так? ведь теоритически можна намного больше
По первой части вопроса: это зависит от многих параметров, не про виндовс, но се же полезно: http://www.kegel.com/c10k.html поищи на сайтенге rsdn.ru статью, там раскрывается что это такое. IO Completion Port да и сайтенг мсдн посмотри. Вот еще хорошая ссылка - http://www.jetbyte.com/portfolio-showarticle.asp?articleId=38&catId=1&subcatId=2 правда примеры ввиде классов, если тебя это остановить - нужна книга огланда, сетевое программирование в виндовс кажется так. По второй части: твой код не видели, обсуждать нечего.
Cock Код (Text): const WM_NET_START = $0402; var Server_S: TSocket; Port: Word; CanDo: Boolean = True; procedure TForm1.FormCreate(Sender: TObject); begin Application.OnMessage := ApplicationMessage; Application.Title := 'Test'; if not Sock_Init then begin ShowMessage('Can''t Init!'); Application.Terminate; end; Server_S := Sock_CreateSocket(True, 555); if Server_S = SOCKET_ERROR then begin Sock_Free; ShowMessage('Can''t open port'); Application.Terminate; end; WSAAsyncSelect(Server_S, Handle, WM_NET_START, fd_accept); Listen(Server_S, 300); Port := 0; end; procedure TForm1.ApplicationMessage(var Msg: tagMSG; var Handled: Boolean); var cl: PUser; i : Integer; begin if (Msg.message >= WM_NET_START) and (Msg.message < WM_NET_START + 1024) then if WSAGETSELECTERROR(Msg.lParam) = 0 then begin case WSAGetSelectEvent(msg.lParam) of fd_accept: begin New(cl); i := SizeOf(cl^.addr); cl^.Sock := Accept(Server_S, @cl^.addr, @i); CanDo := True; end; end; end; Handled := False; end; procedure TForm1.FormDestroy(Sender: TObject); begin Sock_Free; end; procedure TForm1.Start_btnClick(Sender: TObject); begin System_tmr.Enabled := not System_tmr.Enabled; if System_tmr.Enabled then Start_btn.Caption := 'Stop' else Start_btn.Caption := 'Start'; end; procedure TForm1.System_tmrTimer(Sender: TObject); var Client: TSocket; begin if CanDo then begin Client := Sock_CreateSocket(False, 0); if not Sock_Connect(Client, PChar('127.0.0.1'), 555) then begin Start_btn.OnClick(self); ShowMessage('No'); end else inc(Port); CanDo := False; Count_edt.Text := IntToStr(Port); end; end; Извените за корявость, ето темп-программа
Cock Можна другой инфы об nt iocp, а то анг неочень знаю и лутче для Винды, извеняюсь за то что перебираю, но я новичок в сетевом программировании, буду очень признателен если небольшые екзамплы даш, или ссылки на них. Я нашел небольшой http://www.pcdog.com/p/html/2005330/30320057224_3.htm - но там всё с иероглифами. Зарание Благодарен
AntiB тогда эту книгу нужно найти: http://books.dore.ru/bs/f1bid738.html и повторюсь этот исходник http://www.jetbyte.com/portfolio-showarticle.asp?articleId=38&catId=1&subcatId=2 ну и смореть что такое iocp для пущего пониманию в winkd
slow Ето стандартные компоненты? если да - то где они? есил нет - тогда где можна скачать? Ктото смотрел мои исходники - почему я немогу создать более 4 000 сойденений? Зарание Благодарен
Можно сказать, что использовать очередь сообщений, для уведомления о событиях сокетов не очень хорошо, хотя и не возбраняется, но если необходимы высокие скорости и количество соеденений, то лучше отказаться от них и от компонентов делфи
AntiB synapse.ararat.cz Cock где то, не помню точно, видел на дельфи реализацию сервера на iocp. ссылка на ее есть на codeproject в статье про многопотоковый iocp сервер (там код фактически содран с дельфевого исходника)
И ищо, можна точный ответ - куда копать, тоесть какой метод хорош? а то много интересных и умных идей услышал, но всё по разному говорят делать - то как лутче? Зарание Спасибо