![]() |
|
#1
|
||||
|
||||
![]() Начал разбираться с WinSock, для "самообучения" решил написать простой сервер...
Код:
program Server; {$APPTYPE CONSOLE} uses Windows, WinSock; var WSAData: TWSAData; s,clnt: TSocket; inaddr,addrfrom: sockaddr_in; Terminated:boolean; len:integer; function IntToStr(i:integer):string; var s:string; begin str(i,s); Result:=s; end; begin writeln('running...'); if WSAStartup($101,WSAData)<>0 then begin writeln('Error WSAStartup '+IntToStr(WSAGetLastError())); end; writeln('started...'); s:=socket(AF_INET,SOCK_STREAM,0); if s<0 then begin writeln('Error socket '+IntToStr(WSAGetLastError())); end; writeln('sock init...'); inaddr.sin_family:=AF_INET; inaddr.sin_port:=htons(666); inaddr.sin_addr.S_addr:=INADDR_ANY; if bind(s,inaddr,sizeof(inaddr))>0 then begin writeln('Error bind '+IntToStr(WSAGetLastError())); end; writeln('binded...'); if listen(s,SOMAXCONN)>0 then begin writeln('Error listen '+IntToStr(WSAGetLastError())); end; writeln('Listening port 666...'); Terminated:=false; while not Terminated do begin clnt:=accept(s,@addrfrom,@len); writeln('connected '+IntToStr(clnt)); //<=== end; writeln('sock close...'); closesocket(s); writeln('cleanup...'); WSACleanUp; writeln('terminated...'); sleep(10000); end. Где у меня ошибка? (Только не говорите "в ДНК", ламерами все были в той или иной области, все учатся ![]() Яндекс юзал, нашёл статью "Игры на WinSock", по Сишным примерам понял основное, НО... Кстати, какую инфу посоветуете почитать? Оставайтесь хорошими людьми... VK id2634397, ds [at] phoenix [dot] dj Последний раз редактировалось PhoeniX, 19.08.2009 в 10:02. |
#2
|
||||
|
||||
![]() Тоже буквально на днях сделал по примеру криса эхо-сервер. Отлично все работает.
Код:
program wsServer; {$APPTYPE CONSOLE} uses Windows, WinSock; const hello_message = 'Hello!'#0; var ClientsCount : Integer = 0; DefaultPort : Cardinal = 666; //Для каждого подключения создается поток function ClientThread( client_socket : Pointer) : DWORD; stdcall; var sock : TSocket; buff : array [0..1024] of char; bytes_recv : Integer; b : Byte; begin sock := pInteger(client_socket)^; //выводим приглашение buff := 'hi'; send(sock, buff, 3, 0); //цикл обработки сообщений repeat bytes_recv := recv(sock, buff, 1024, 0); if bytes_recv = 0 then Break; send(sock, buff, bytes_recv, 0); until false; //при разрыве соединения клиентом цикл завершается Writeln('Dosconnect'); closesocket(sock); end; procedure Main; var buff : array[0..1024] of Char; wsadat : TWSAData; Socket : TSocket; local_addr : sockaddr_in; client_socket : TSocket; client_addr : sockaddr_in; client_addr_size : Integer; hst : HOSTENT; thID : Cardinal; begin Writeln('TCP SERVER'); //инициализация if WSAStartup($0202, wsadat) <> 0 then begin Writeln('WSAStartup error #', WSAGetLastError); Readln; Exit; end; //создание сокета Socket := WinSock.socket(AF_INET, SOCK_STREAM, 0); if Socket < 0 then begin Writeln('socket error #', WSAGetLastError); Readln; Exit; end; //связывание сокета с локальным адресом local_addr.sin_family := AF_INET; local_addr.sin_port := htons(DefaultPort); local_addr.sin_addr.s_addr := 0; if Bind(Socket, local_addr, SizeOf(local_addr)) <> 0 then begin Writeln('Bind error #', WSAGetLastError); Readln; Exit; end; //ожидание подключений if listen(Socket, $100) <> 0 then begin Writeln('Socket error #', WSAGetLastError); Readln; Exit; end; WriteLn('Wait for connections'); //извлекаем сообщение из очереди client_addr_size := Sizeof(client_addr); //ожидание подключений repeat client_socket := accept(Socket, @client_addr, @client_addr_size); if client_socket = 0 then Break; Writeln('Connect'); CreateThread(nil, 0, @ClientThread, @client_socket, 0, thID); //@client_socket лучше заменить на Pointer(client_socket) и в процедуре потока исправить, а то мало ли - затрется. until false; end; begin Main end. Сейчас скачал "Программирование в сетях Microsoft Windows" (Э. Джонс, Д. Оланд). Читаю, детально все описано. ...сказал, и загрустил от бесспорной своей правоты Последний раз редактировалось 0nni, 19.08.2009 в 19:02. |
#3
|
||||
|
||||
![]() Ура, работает! Забыл инициализировать переменную
Код:
len:=sizeof(addrfrom); Сейчас буду делать парсер HTTP заголовков, потом прикручу настройки, авто-перезагрузку через определённое в настройках время... короче, "фантики". Прилагаю, что есть сейчас: Код:
program Server; {$APPTYPE CONSOLE} uses Windows, WinSock, MainThread in 'MainThread.pas'; var WSAData: TWSAData; s,clnt: TSocket; inaddr,addrfrom: sockaddr_in; Terminated:boolean; len:integer; procedure ParseNewConnection(client_socket:TSocket); var sock : TSocket; buff : array [0..25523] of char; bytes_recv : Integer; begin sock := client_socket; buff := 'hi'; repeat bytes_recv := recv(sock, buff, 1024, 0); if (bytes_recv = 0)or(bytes_recv<1024) then Break; until false; WriteLn(buff); buff:='HTTP/1.1 200 OK'#10+ 'Content-length: 5'#10+ ''#10+ 'Hello'; send(sock, buff, Length(buff), 0); Writeln('Disconnect'); closesocket(sock); end; function IntToStr(i:integer):string; var s:string; begin str(i,s); Result:=s; end; begin writeln('running...'); if WSAStartup($202,WSAData)<>0 then begin writeln('Error WSAStartup '+IntToStr(WSAGetLastError())); exit; end; writeln('started...'); s:=socket(AF_INET,SOCK_STREAM,0); if s<0 then begin writeln('Error socket '+IntToStr(WSAGetLastError())); exit; end; writeln('sock init...'); inaddr.sin_family:=AF_INET; inaddr.sin_port:=htons(666); inaddr.sin_addr.S_addr:=0; if bind(s,inaddr,sizeof(inaddr))<>0 then begin writeln('Error bind '+IntToStr(WSAGetLastError())); exit; end; writeln('binded...'); if listen(s,$100)<>0 then begin writeln('Error listen '+IntToStr(WSAGetLastError())); exit; end; writeln('Listening port 12345...'); Terminated:=false; len:=sizeof(addrfrom); while not Terminated do begin clnt:=accept(s,@addrfrom,@len); writeln('Connected'); ParseNewConnection(clnt); end; writeln('sock close...'); closesocket(s); writeln('cleanup...'); WSACleanUp; writeln('terminated...'); sleep(10000); end. Оставайтесь хорошими людьми... VK id2634397, ds [at] phoenix [dot] dj |