О чём не пишут в книгах по Delphi
Шрифт:
ServerAddr.sin_port := htons(StrToInt(EditPort.Text));
// Создание сокета
FSocket := socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if FSocket = INVALID_SOCKET then
begin
MessageDlg('Ошибка при создании сокета: '#13#10 +
GetErrorString, mtError, [mbOK], 0);
Exit;
end;
//
Подключение к серверу
if connect(FSocket, ServerAddr, SizeOf(ServerAddr)) < 0 then
begin
MessageDlg('Ошибка при установлении подключения: '#13#10 +
GetErrorString, mtError, [mbOK], 0);
// Так как сокет был успешно создан,
// в случае ошибки его нужно удалить
closesocket(FSocket);
FSocket := 0;
Exit;
end;
// Включаем режим "Соединение установлено"
OnConnect;
except
on EConvertError do
// Это исключение может возникнуть только в одном месте -
// при вызове StrToInt(EditPort.Text)
MessageDlg('"' + EditPort.Text + '"не является целым числом',
mtError, [mbOK], 0);
on ERangeError do
// Это исключение может возникнуть только в одном месте -
// при присваивании значения номеру порта
MessageDlg('Номер порта должен находиться в диапазоне 1-65535',
mtError, [mbOK], 0);
end;
end;
Теперь посмотрим, как клиент реагирует на нажатие кнопки Отправить (листинг 2.17). Сама по себе отправка — вещь очень простая: нужно сформировать адрес получателя и вызвать функцию
send
. Несколько сложнее выполняется чтение данных, потому что, согласно нашему протоколу, клиент не знает, сколько байтов он должен прочитать, и читает до тех пор, пока не встретит символ #0
. Листинг 2.17. Обработчик нажатия кнопки Отправить
procedure TSimpleClientForm.BtnSendClick(Sender: TObject);
const
// Данные из буфера сокета мы будем читать порциями.
// константа BufStep определяет размер порции
BufStep = 10;
var
Str: string
StrLen, BufStart, Portion: Integer;
Buf: array of Char;
begin
Str := EditStringToSend.Text;
StrLen := Length(Str);
if StrLen = 0 then
begin
MessageDlg('Протокол
не допускает отправки пустых строк',
mtError, [mbOK], 0);
Exit;
end;
// отправляем серверу длину строки
if send(FSocket, StrLen, SizeOf(StrLen), 0) < 0 then
begin
MessageDlg('Ошибка при отправке данных серверу '#13#10 +
GetErrorString, mtError, [mbOK], 0);
OnDisconnect;
Exit;
end;
// Отправляем серверу строку
if send(FSocket, Str[1], StrLen, 0) < 0 then
begin
MessageDlg('Ошибка при отправке данных серверу: '#13#10 +
GetErrorString, mtError, [mbOK], 0);
OnDisconnect;
Exit;
end;
BufStart := 0;
// Цикл получения ответа от сервера
// завершается, когда получаем посылку, оканчивающуюся на #0
repeat
SetLength(Buf, Length(Buf) + BufStep);
// Читаем очередную порцию ответа от сервера
Portion := recv(FSocket, Buf(BufStart), BufStep, 0);
if Portion <= 0 then
begin
MessageDlg('Ошибка при получении ответа от сервера: '#13#10 +
GetErrorString, mtError, [mbOK], 0);
OnDisconnect;
Exit;
end;
// Если порция кончается на #0, ответ прочитан полностью, выходим из
// цикла. Здесь мы использовали особенность нашего протокола, который
// запрещает серверу присылать несколько строк подряд, следующая
// строка будет выслана сервером только после нового запроса от
// клиента. Если бы протокол допускал отправку сервером нескольких
// ответов подряд, при чтении очередной порции данных могло бы
// оказаться, что начало порции принадлежит одной строке, конец -
// следующей, а признак конца строки нужно искать где-то в середине
if Buf[BufStart + Portion - 1] = #0 then
Поделиться:
Популярные книги
Замуж второй раз, или Ещё посмотрим, кто из нас попал!
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Протокол "Наследник"
1. Гибрид
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Сердце Дракона. Том 11
11. Сердце дракона
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
6.50
рейтинг книги
Вперед в прошлое!
1. Вперед в прошлое
Фантастика:
попаданцы
5.00
рейтинг книги
Шесть принцев для мисс Недотроги
3. Мисс Недотрога
Фантастика:
фэнтези
7.92
рейтинг книги
Хочу тебя любить
Любовные романы:
современные любовные романы
5.67
рейтинг книги
Огни Аль-Тура. Желанная
3. Эйнар
Любовные романы:
любовно-фантастические романы
эро литература
5.25
рейтинг книги
Начальник милиции 2
2. Начальник милиции
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Мастер...
1. Мастер
Фантастика:
героическая фантастика
попаданцы
аниме
6.50
рейтинг книги
Сумеречный стрелок 8
8. Сумеречный стрелок
Фантастика:
городское фэнтези
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Я до сих пор не князь. Книга XVI
16. Дорогой барон!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Обыкновенные ведьмы средней полосы
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Метаморфозы Катрин
Фантастика:
фэнтези
8.26
рейтинг книги
Идеальный мир для Социопата
1. Социопат
Фантастика:
боевая фантастика
рпг
постапокалипсис
6.17