Чтение онлайн

ЖАНРЫ

О чём не пишут в книгах по Delphi

Григорьев Антон Борисович

Шрифт:

if ServerAddr.sin_port = 0 then

begin

MessageDlg('Номер порта должен находиться в диапазоне 1-65535',

mtError, [mbOK], 0);

Exit;

end;

// Создание сокета для получения сообщений

ServerSocket := socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

if ServerSocket = INVALID_SOCKET then

begin

MessageDlg('Ошибка
при создании сокета: '#13#10 + GetErrorString,

mtError, [mbOK], 0);

Exit;

end;

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

if bind(ServerSocket, ServerAddr, SizeOf(ServerAddr)) = SOCKET_ERROR then

begin

MessageDlg('Ошибка при привязке сокета к адресу: '#13#10 + GetErrorString,

mtError, [mbOK], 0);

closesocket(ServerSocket);

Exit;

end;

// Создание нити, которая будет получать сообщения.

// Сокет передается ей, и дальше она отвечает за него.

TReceiveThread.Create(ServerSocket);

// Перевод элементов управления в состояние "Сервер работает"

LabelServerPort.Enabled := False;

EditServerPort.Enabled := False;

BtnStartServer.Enabled := False;

LabelServerState.Caption:= 'Сервер работает';

 except

on EConvertError do

// Это исключение может возникнуть только в одном месте -

// при вызове StrToInt(ЕditServerPort.Text)

MessageDlg('"' + EditServerPort.Text +

'" не является целым числом', mtError, [mbOK], 0);

on ERangeError do

// Это исключение может возникнуть только в одном месте -

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

MessageDlg('Номер порта должен находиться в диапазоне 1-65535",

mtError, [mbOK], 0);

 end;

end;

Для отправки сообщения пользователь должен нажать кнопку Отправить. При этом формируется адрес на основании введённых пользователем данных и вызывается функция

sendto
(листинг 2.10). Пользователь должен каким-то образом узнать, какой порт назначения выбран у адресата. Его IP-адрес тоже, разумеется, необходимо знать.

Листинг 2.10. Обработчик нажатия кнопки Отправить

// Реакция на кнопку "Отправить"

procedure TChatFormBtnSendClick(Sender: TObject);

var

 // Адрес назначения SendAddr: TSockAddr;

 // Сообщение для отправки

 Msg: string;

 //
Результат отправки

 SendRes: Integer;

begin

 // Формируем адрес назначения на основе того,

 // что пользователь ввел в соответствующие поля

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

 SendAddr.sin_family := AF_INET;

 SendAddr.sin_addr.S_addr := inet_addr(PChar(EditSendAddr.Text));

 // Для совместимости со старыми версиями Delphi приводим

 // константу INADDR_NONE к типу u_long

 if SendAddr.sin_addr.S_addr = u_long(INADDR_NONE) then

 begin

MessageDlg('"' +EditSendAddr.Text + '"не является IP-адресом',

mtError, [mbOK], 0);

Exit;

 end;

 try

SendAddr.sin_port := htons(StrToInt(EditSendPort.Text));

// Получаем сообщение, которое ввел пользователь.

// Дополнительная переменная понадобилась потому,

// что нам потребуется ее передавать в качестве var-параметра,

// а делать это со свойством EditMessage.Техt нельзя.

Msg := EditMessage.Text;

if Length(Msg) = 0 then

// Отправляем дейтаграмму нулевой длины -

// протокол UDP разрешает такое

SendRes := sendto(FSendSocket, Msg, 0, 0, SendAddr, SizeOf(SendAddr))

else

// Отправляем сообщение, содержащее строку

SendRes := sendto(FSendSocket, Msg[1], Length(Msg), 0, SendAddr, SizeOf(SendAddr));

if SendRes < 0 then

MessageDlg('Ошибка при отправке сообщения:'#13#10 + GetErrorString,

mtError, [mbOK], 0)

else

AddMessageToLog('Для ' + EditSendAddr.Text + ':' + EditSendPort.Text +

' отправлено сообщение: ' + Msg);

 except

on EConvertError do

// Это исключение может возникнуть только в одном месте -

// при вызове IntToStr(EditSendPort.Text)

MessageDlg('"' + EditSendPort.Text + не является целым числом',

mtError, [mbOK], 0);

on ERangeError do

// Это исключение может возникнуть только в одном месте -

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

MessageDlg('Номер порта должен находиться в диапазоне 1-65535',

mtError, [mbOK], 0);

Поделиться с друзьями: