Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
prakt-Storozhok.docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
7.98 Mб
Скачать

1.2.4. Передача данных

function sendto(

s: TSocket;

var buf; len, flags: Integer;

var addrto: TSockAddr;

tolen: Integer

): Integer; stdcall;.

Первый параметр s определяет сокет для отправки данных.

Второй параметр - buf, указывает на символьный буфер, содержащий данные для отправки.

Третий - len, задает число отравляемых из буфера символов.

Параметр - flags, может принимать значения 0, MSG_DONTROUTE, MSG_ООВ или результат логического ИЛИ над любыми из этих параметров. При указании флага MSG_DONTROUTE транспорт не будет маршрутизировать отправляемые пакеты. Обработка этого запроса остается на усмотрение базового протокола (например, если транспорт не поддерживает этот параметр, запрос игнорируется). Флаг MSG_ООВ указывает, что данные должны быть отправлены вне полосы (out of band), то есть срочно.

Параметр addrto - указатель на структуру SockAddr_in с адресом принимающей рабочей станции.

Параметр tolen - длина структуры addrto.

При успешном выполнении функция sendem вернет количество переданных байт, иначе - ошибку SOCKET_ERROR.

1.2.5. Получение данных по сети

function recvfrom(

s: TSocket;

var Buf; len, flags: Integer;

var from: TSockAddr;

var fromlen: Integer

): Integer; stdcall;

Первый параметр s определяет сокет для приема данных.

Второй параметр - buf, является символьным буфером и предназначен для полученных данных, а len указывает число принимаемых байт или размер буфера buf.

Параметр - flags, может принимать значения 0, MSG_РЕЕК, MSG_OOB или результат логического ИЛИ над любыми из этих параметров. Разумеется, 0 означает отсутствие особых действий. Флаг MSG_PEEK указывает, что доступные данные должны копироваться в принимающий буфер и при этом оставаться в системном буфере. По завершении функция также возвращает количество ожидающих байт. Считывать сообщения таким образом не рекомендуется. Флаг MSG_OOB означает, что пришли срочные данные.

Параметр from - указатель на структуру SockAddr_in для данного протокола. После выполнения функции параметр from будет содержать адрес рабочей станции, которая отправляет данные.

Параметр fromlen - длина параметра from в байтах.

1.2.6. Закрытие сокета

function closesocket(

s: Tsocket

): Integer; stdcall;,

где s - дескриптор сокета.

Функция закрывает одну сторону в соединении.

1.2.7. Деинициализация интерфейса сокетов

function WSACleanup: Integer; stdcall;.

Функция уведомляет библиотеку Winsock, что приложение закончило работу с сокетами.

1.3. Алгоритм работы Winsock-приложения по протоколу UDP

Алгоритм работы Winsock-приложения, работающего по протоколу UDP, приведен на рис. 1.

2. Задание по практическому занятию

2.1. Создание серверного приложения

При реализации серверного приложения выполнить следующие пункты.

1) Создать Серверное приложение, имеющее вид, представленный на рис. 2.

2) Подключить библиотеку сокетов. Для этого в блок uses добавить библиотеку Winsock:

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, StdCtrls, Winsock;

  1. Инициализировать интерфейс сокетов с помощью функции WSAStartup.

  2. Создать сокет с помощью функции socket.

  3. Объявить с помощью функции Bind, на каком порту сервер будет принимать данные и от кого.

  4. Получить данные от любого клиента с помощью функции recvfrom.

  5. Вывести на экран полученное сообщение.

Клиент

Сервер

WSAStartup

WSAStartup

socket

socket

Передача сообщения от клиента к серверу

bind

recvfrom

sendto

Передача ответа от сервера к клиенту

sendto

CloseSocket

WSACleanup

Рис. 1. Алгоритм работы клиента и сервера по передаче датаграмм в эхорежиме

WSACleanup

CloseSocket

recvfrom

Рис. 2

  1. Возвратить полученное сообщение клиенту в эхорежиме с помощью функции sendto.

  2. Закрыть сокет с помощью функции CloseSocket и прекратить работу с интерфейсом сокетов с помощью функции WSACleanup.

Для выполнения перечисленных действий событие OnClick командной кнопки «Запуск сервера» может быть представлено следующим программным кодом:

procedure TForm1.Button1C1ick( Sender: TObject);

VAR

s: TSocket; {Сокет}

local_socket, sender_socket: TSockAddr; {адреса сокета сервера и сокета отправителя}

ret: Integer; {результат работы функций}

bufr: Array [1..90] of char; {буфер для получаемых от клиента данных}

msgstring: Array [1..90] of char; {буфер для вывода сообщения на экран}

bufs: Array [1..80] of char; {буфер для передачи ответа клиенту} wsd: WSADAТА;{Структура WSADATA, требуется для инициализации интерфейса сокетов}

size_socket: Integer; {размер структуры TSockAddr}

begin

//Инициализация интерфейса сокетов

If WSAStartup(MAKEWORD(2,2),wsd)<>0

then ShowMessageFmt('Ошибка %d при инициализации интерфейса сокетов', [WSAGetLastError])

else

begin

// Создание сокета сервера

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

If s=INVALID_SOCKET

Then ShowMessageFmt('Ошибка %d при создании

Сокета',[WSAGetLastError]) else

Begin

// Запись в поля переменной local адреса и номера порта сервера,

// по которому сервер будет принимать датаграммы

Local_socket. Sin_family :=AF_INET;

Local_socket.sin_port := htons(2000);

Local_socket.sin_addr.S_addr:=htonl(lNADDR_ANY);

// привязка адреса и номера порта к сокету сервера

// т. е. сервер ожидает данные от любого клиента (INADDR_ANY)

// если данные передаются на порт 2000

ret := bind(s,local_socket, sizeof(local_socket));

If ret=SOCKET_ERROR then

begin

ShowMessageFmt('Ошибка %d при объявлении сокета',

[WSAGetLastError]);

CloseSocket(s);

end

else

begin

ret:=0;

size_socket:= Sizeof(sender_ socket);

ZeroMemory(@bufr, sizeof(bufr));

// Получение данных от клиента

ret := recvfrom(s, bufr, sizeof(bufr), 0, sender_socket, size_socket);

If ret=SOCKET_ERROR then

ShowMessageFmt('Ошибка %d при получении данных ',

[WSAGetLastError])

else

begin

// Формирование сообщения msgstring для вывода на экран

StrCopy(@msgstring, 'Получено сообщение:');

StrCat(@msgstring, @bufr);

StrCat(@msgstring,' от');

StrCat(@msgstring,inet_ntoa(sender_socket.sin_addr));

ShowMessage(msgstring);

end;

StrCopy(@bufs, @bufr);

// Пересылка эхоответа клиенту

ret :=sendto(s, bufs, sizeof(bufs), 0, sender_socket, sizeof(sender socket));

If ret=SOCKET_ERROR then

begin

ShowMessageFmt('Ошибка %d при передаче данных ',

[WSAGetLastError]);

CloseSocket(s);

end;

// закрытие сокета

CloseSocket(s);

end; end;

WSACleanup;

end;

end;.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]