Работа с UDP в Delphi

Cети и Интернет   4 февраля 2012  Автор статьи: admin 

Скачать пример работы с UDP + модуль, значительно упрощающий работу с UDP.

В этой статье мы рассмотрим основные принципы работы с транспортным протоколом UDP в Delphi, а также все плюсы и минусы UDP по сравнению с TCP.
Для начала рассмотрим саму суть транспортного механизма UDP.
UDP (англ. User Datagram Protocol — протокол пользовательских датаграмм) позволяет осуществлять передачу данных без предварительной установки соединения. По сравнению с TCP, UDP не может гарантировать доставку пакета с информацией, что позволяет ему гораздо быстрее доставлять данные. UDP выгодно использовать в приложениях, где происходит очень частая отправка данных, т.е. где требуется высокая пропускная способность линии связи.
Приступим к созданию простого примера работы с UDP.
Для начала подключим модуль WinSock, который позволяет работать с сокетами.
Объявим тип, которым будут представлены пакеты передаваемых данных:
[cc lang=»delphi»]TPacket = packed record
mode: byte;
pack: array [0 .. 9999] of Char;
end;[/cc]
Для примера я объявил запись, состоящую из mode и pack. Передаваемые пакеты могут быть и такими. Такие пакеты очень удобно обрабатывать при получении, т.к. их структура нам будет уже ясна.
Объявим следующие глобальные переменные:
[cc lang=»delphi»]var
Sock: TSocket; // сокет
ServerAddr: TSockAddrIn; // здесь будет храниться информация
// для взаимодействия между приложениями
wData: TWSAData;[/cc]

Теперь приступим непосредственно к инициализации сокета:
[cc lang=»delphi»]procedure InitUDP;
begin
WSAStartup($0101, wData);
Sock := socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); // SOCK_DGRAM означает,
// что мы будем работать с транспортным протоколом UDP
ServerAddr.sin_family := AF_INET;
ServerAddr.sin_port := htons(666);
bind(Sock, ServerAddr, SizeOf(ServerAddr));
CreateThread(nil, 0, @RecvProc, nil, 0, LongWord(nil^));
// здесь мы создаем поток, в котором реализуем получение пакетов
end;[/cc]

Теперь реализуем поток, который будет осуществлять прием данных:
[cc lang=’delphi’]procedure RecvProc(Param: Pointer); stdcall;
var
Count: LongInt;
from: TSockAddrIn;
FromLen: LongInt;
Packet: TPacket;
i, j: LongInt;
begin
while True do // зацикливаем поток
begin
FromLen := SizeOf(from);
Count := recvfrom(Sock, Packet, SizeOf(Packet), 0, from, FromLen); // считываем данные
if Count > 0 then
begin
ExecutePacket(Packet{сам пакет},
string(inet_ntoa(from.sin_addr)){IP-адрес отправителя пакета});
end;
end;
end;[/cc]
В этом потоке мы получаем пакет, IP адрес отправителя этого пакета и передаем эти данные процедуре ExecutePacket, которая будет обрабатывать полученную информацию. В нашем случае мы просто выведем на экран содержимое полученного пакета в виде обыкновенного сообщения:
[cc lang=’delphi’]procedure ExecutePacket(pack: TPacket{сам пакет};
from: AnsiString{IP-адрес отправителя пакета});
begin
ShowMessage(pack.pack);
end;[/cc]
Теперь реализуем отправку пакета с данными. Реализуем следующую процедуру:
[cc lang=’delphi’]procedure SendToIP(fip: AnsiString; fpack: string; fmode: byte);
procedure Send(var Packet: TPacket; var Addr: TSockAddrIn);
// эта процедура реализует непосредственную отправку собранного пакета
// по указанным в Addr данным
begin
sendto(Sock, Packet, SizeOf(Packet), 0, Addr, SizeOf(Addr));
end;
var
PacketToSend: TPacket; // собираемый пакет
i: integer;
begin
ServerAddr.sin_port := htons(666);
ServerAddr.sin_addr.S_addr := inet_addr(PAnsiChar(fip)); // указываем IP получателя пакета
PacketToSend.mode := fmode; // собираем пакет
PacketToSend.pack := #0; // необходимо работать не с типом string, а array of char.
// поэтому преобразуем string в array of char следующим образом:
for i := 0 to length(fpack) — 1 do
PacketToSend.pack[i] := Char(fpack[i + 1]);
// отправляем собранный пакет
Send(PacketToSend, ServerAddr);
end;[/cc]

Ну, и наконец, реализуем процедуру закрытия сокета:
[cc lang=»delphi»]procedure DestroyUDP;
begin
closesocket(Sock);
WSACleanup;
end;[/cc]

Таким образом можно реализовать работу с транспортным протоколом UDP. Вы также можете скачать рабочий пример. К этому примеру прилагается модуль, позволяющий реализовывать работу с UDP в 3 строки программного кода абсолютно без каких-либо затруднений. Работать с таким модулем гораздо легче и удобнее. Скачать все это вы можете отсюда.

  • Дмитрий

    При всем уважении, я понимаю когда в примерах не пишут проверок на ошибки (хотя даже тогда принято пояснять для новичков, что проверки опущены для краткости), но когда предлогают «готовый модуль» без них это уже перегиб. А уж незавершенный поток в принципе не иеющий точки выхода это отдельный перл.

  • Евгений

    Здравствуйте, я начинающий. А как чтение организовать с конкретного ip?

Научиться программировать

  • на Delphi

  • на Java

  • на C++