![]() |
|
|
#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", по Сишным примерам понял основное, НО... Кстати, какую инфу посоветуете почитать? Последний раз редактировалось 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. |