Читаем О чём не пишут в книгах по Delphi полностью

Для получения целостной картины кратко повторим все сказанное. Для установления соединения сервер должен, во-первых, создать сокет с помощью функции socket, а во-вторых, привязать его к адресу с помощью функции bind. Далее сокет должен быть переведен в режим ожидания с помощью listen, а потом с помощью функции accept создается новый сокет, обслуживающий соединение, установленное клиентом. После этого сервер может обмениваться данными с клиентом. Клиент же должен создать сокет, при необходимости привязки к конкретному порту вызвать bind, и затем вызвать connect для установления соединения. После успешного завершения этой функции клиент может обмениваться данными с сервером. Это иллюстрируют листинги 2.11 и 2.12.

Листинг 2.11. Код сервера

var

 S, AcceptedSock: TSocket;

 Addr: TSockAddr;

 Data: TWSAData;

 Len: Integer;

begin

 WSAStartup($101, Data);

 S := socket(AF_INET, SOCK_SТREAМ, 0);

 Addr.sin_family := FF_INET;

 Addr.sin_port := htons(3030);

 Addr.sin_addr.S_addr := INADDR_ANY;

 FillChar(Addr.sin_zero, SizeOf(Addr.sin_zero), 0);

 bind(S, Addr, SizeOf(TSockAddr));

 listen(S, SOMAXCONN);

 Len := SizeOf(TSockAddr);

 AcceptedSock := accept(S, @Addr, @Len);

 {

  Теперь Addr содержит адрес клиента, с которым установлено соединение, а AcceptedSock - дескриптор, обслуживающий это соединение. Допустимы следующие действия:

  send(AcceptedSock, ...) - отправить данные клиенту

  recv(AcceptedSock, ...) - получить данные от клиента

  accept(...) - установить соединение с новым клиентом

 }

Здесь сокет сервера привязывается к порту с номером 3030. В общем случае разработчик сервера сам должен выбрать порт из диапазона 1024–65 535.

Листинг 2.12. Код клиента

var

 S: TSocket;

 Addr: TSockAddr;

 Data: TWSAData;

begin

 WSAStartup($101, Data);

 S := socket(AF_INET, SOCK_STREAM, 0);

 Addr.sin_family := AF_INET;

 Addr.sin_port := htons(3030);

 Addr.sin_addr.S_addr := inet_addr(...);

 FillChar(Addr.sin_zero, SizeOf(Addr.sin_zero), 0);

 connect(S, Addr, SizeOf(TSockAddr));

 {

  Теперь соединение установлено. Допустимы следующие действия:

  send(S, ...) - отправить данные серверу

  recv(S, ...) — получить данные от сервера

 }

В приведенном коде для краткости опущены проверки результатов функций с целью обнаружения ошибок. При написании серьезных программ этим пренебрегать нельзя. Блок-схема действии клиента и сервера приведена на рис. 2.3.

Перейти на страницу:
Нет соединения с сервером, попробуйте зайти чуть позже