Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Интернет и сети
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 19.08.2009, 10:00
Аватар для PhoeniX
PhoeniX PhoeniX вне форума
Always hardcore!
 
Регистрация: 04.03.2009
Адрес: СПб
Сообщения: 3,239
Версия Delphi: GCC/FPC/FASM
Репутация: 62149
По умолчанию WinSock

Начал разбираться с 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.
В итоге получаю толпу вывода "connected -1" (выводит помеченная строчка).
Где у меня ошибка? (Только не говорите "в ДНК", ламерами все были в той или иной области, все учатся )
Яндекс юзал, нашёл статью "Игры на WinSock", по Сишным примерам понял основное, НО...
Кстати, какую инфу посоветуете почитать?
__________________
Оставайтесь хорошими людьми...
VK id2634397, ds [at] phoenix [dot] dj

Последний раз редактировалось PhoeniX, 19.08.2009 в 10:02.
Ответить с цитированием
  #2  
Старый 19.08.2009, 17:43
Аватар для 0nni
0nni 0nni вне форума
Начинающий
 
Регистрация: 13.12.2008
Адрес: Туапсе
Сообщения: 161
Репутация: 20
По умолчанию

Тоже буквально на днях сделал по примеру криса эхо-сервер. Отлично все работает.

Код:
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  
Старый 19.08.2009, 19:33
Аватар для PhoeniX
PhoeniX PhoeniX вне форума
Always hardcore!
 
Регистрация: 04.03.2009
Адрес: СПб
Сообщения: 3,239
Версия Delphi: GCC/FPC/FASM
Репутация: 62149
По умолчанию

Ура, работает! Забыл инициализировать переменную
Код:
  len:=sizeof(addrfrom);
сделал пародию на HTTP сервер - работает.
Сейчас буду делать парсер 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
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 13:32.


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2025