- •Часть 1
- •Устройство вычислительной системы на основе ibm pc-совместимого компьютера
- •Порядок выполнения работы.
- •1.3.Заполните таблицу:
- •Получение навыков в сборке и настройке пк
- •Порядок выполнения.
- •Заполните таблицу.
- •Изучить компоненты, входящие в состав материнской платы.
- •3.1. Изучить компоненты, входящие в состав материнской платы.
- •Порядок выполнения.
- •Теоретическое введение
- •Установление соединения
- •Перевод сокета в режим пассивного ожидания
- •Блокирование выполнения программы до тех пор, пока не поступит запрос на установление соединения
- •Передача данных
- •Получение данных по сети
- •Задание к работе
- •Создание клиентского приложения
- •Дополнительные задания
- •Контрольные вопросы
- •2.Исследование протоколов ftp
- •3.Исследование протоколов Telnet, smtp, pop, imap
- •Пример электронного письма
- •Дополнительная литература
- •Оглавление
- •Горбунов Андрей Михайлович вычислительные системы, сети и телекоммуникации сборник лабораторных работ
- •Часть 1
Теоретическое введение
Алгоритм передачи
информации между клиентом и сервером
по протоколу TCP изображен
на рис. 1.
Часть функций библиотеки Winsock рассмотрена в предыдущей работе. Новые функции рассмотрены ниже.
Установление соединения
Установление соединения выполняется на стороне клиента с помощью функции connect:
function connect(
s: TSocket;
var name: TSockAddr;
namelen: Integer): Integer; stdcall;
где
s – входной параметр. Дескриптор сокета, созданного с помощью функции socket.
name – входной/выходной параметр. Структура sockaddr (адрес удаленного сокета). В данном случае IP-адрес и порт сервера.
namelen - входной параметр. Длина структуры sockaddr.
В случае ошибки функция возвращает значение SOCKET_ERROR
Перевод сокета в режим пассивного ожидания
Перевод сокета в режим пассивного ожидания выполняется на стороне сервера с помощью функции listen:
function listen(
s: TSocket;
backlog: Integer): Integer; stdcall;
где
s – входной параметр. Дескриптор сокета, созданного с помощью функции socket.
backlog – длина входной очереди сообщений, то есть сколько сообщений может одновременно принять сервер без потери данных. Обычно размер входной очереди равен 5 сообщениям.
Блокирование выполнения программы до тех пор, пока не поступит запрос на установление соединения
Данная функция называется accept и выполняется на стороне сервера
function accept(
s: TSocket;
addr: PSockAddr;
addrlen: PInteger): TSocket; stdcall;
где
s- входной параметр. Дескриптор сокета, созданного с помощью функции socket.
addr – входной/выходной параметр. Структура sockaddr. В данной структуре возвращается адрес сокета клиента, который установил соединение с сервером.
addrlen - Длина структуры sockaddr.
Функция accept возвращает дескриптор сокета, который будут использовать функции recv и send при приеме (передаче) данных от клиента (клиенту).
Передача данных
Передача данных поочередно выполняется на стороне и сервера и клиента. Для передачи данных используется функция send:
function send(
s: TSocket;
var Buf;
len,
flags: Integer): Integer; stdcall;
где
s - дескриптор сокета, созданного с помощью функции socket на стороне клиента, или полученного в результате выполнения функции accept на стороне сервера.
Buf – Буфер, содержит передаваемые данные
Len – длина буфера Buf.
Flags – специальные флаги. Обычно это поле равно 0.
В случае ошибки функция возвращает значение SOCKET_ERROR
Получение данных по сети
Получение данных по сети поочередно выполняется на стороне и сервера и клиента. Для получения
int recv (
SOCKET s,
char FAR* buf,
int len,
int flags
);
function recv(
s: TSocket;
var Buf;
len,
flags: Integer): Integer; stdcall;
где
s - Дескриптор сокета, созданного с помощью функции socket на стороне клиента, или полученного в результате выполнения функции accept на стороне сервера.
Buf – Выходной параметр. Буфер, куда будут записываться принимаемые по сети данные.
Len - входной параметр. Длина буфера Buf.
Flags – флаги. Обычно это поле равно 0.
В случае ошибки функция возвращает значение SOCKET_ERROR
Задание к работе
Создайте клиент-серверное приложение, выполняющее прием и передачу данных по сети. Серверное приложение, имеет вид, показанный на рис.2.
Серверное приложение должно выполнять следующие действия.
Подключить библиотеку Winsock (следует сделать ссылку на библиотеку в списке подключаемых модулей - uses).
Инициализировать интерфейс сокетов с помощью функции WSAStartup.
Создавать сокет с помощью функции socket.
Настраивать сокет с помощью функции setsockopt (необязательно).
Объявлять с помощью функции Bind, на каком порту сервер будет принимать данные и от кого.
Перевести сокет в режим пассивного ожидания с помощью функции listen.
Блокировать выполнения программы до тех пор, пока не поступит запрос на установление соединения с помощью функции accept. Функция accept возвращает дескриптор сокета, на котором будет выполняться прием-передача данных.
Получать данные от любого клиента с помощью функции recv.
Выводить на экран полученное сообщение.
Возвращать полученное сообщение клиенту в режиме эхо с помощью функции send.
Закрывать сокет с помощью функции CloseSocket.
Прекращать работу с интерфейсом сокетов с помощью функции WSACleanup.
Для реализации перечисленных функций сервера выполните следующие действия:
Создайте проект (New Application). Назовите созданный проект каким-либо именем, например – Server.
На созданную форму перенесите две командные кнопки:
Button1 - «Запустить сервер»;
Button2 - «Выход из программы».
Для события OnClick командной кнопки «Запуск сервера» запишите следующий программный код:
procedure TForm1.Button1Click(Sender: TObject);
VAR
ServerSocket,ClientSocket:TSocket; {Сокет}
addr_server,addr_client:TSockAddr; {адреса сокета сервера и
сокета отправителя}
ret:Integer; {результат работы функций}
bufr :Array [1..90] of char;{буфер для получаемых от клиента данных}
msgstring:Array [1..90] of char;{буфер для вывода сообщения на экран}
bufs:Array [1..80] of char; {буфер для передачи ответа клиенту}
wsd:WSADATA;{Структура WSADATA, требуется для инициализации
интерфейса сокетов}
size_addr:Integer; {размер структуры TSockAddr}
on:Integer;
begin
// Инициализация интерфейса сокетов
If WSAStartup(MAKEWORD(2,2),wsd)<>0
then ShowMessageFmt('Ошибка %d при инициализации интерфеса сокетов',
[WSAGetLastError])
else
begin
// Создание сокета сервера
ServerSocket:=socket(AF_INET,SOCK_STREAM,0);
If ServerSocket=INVALID_SOCKET
then ShowMessageFmt('Ошибка %d при создании сокета',
[WSAGetLastError])
else
begin
// Запись в поля переменной local адреса и номера порта сервера,
// по которому сервер будет принимать датаграммы
addr_server.sin_family:=AF_INET;
addr_server.sin_port:=htons(2000);
addr_server.sin_addr.S_addr:=htonl(INADDR_ANY);
// настройка опций сокета
on:=1;
ret:=setsockopt(ServerSocket,SOL_SOCKET,SO_REUSEADDR,
@on,sizeof(on));
If ret=SOCKET_ERROR then
begin
ShowMessageFmt('Ошибка %d при настройке сокета',[WSAGetLastError]);
CloseSocket(ServerSocket);
end
else
begin
// привязка адреса и номера порта к сокету сервера
// т.е. сервер будет ожидать данные от любого клиента (INADDR_ANY)
// если данные передаются на порт 2000
ret:=bind(ServerSocket,addr_server,sizeof(addr_server));
If ret=SOCKET_ERROR then
begin
ShowMessageFmt('Ошибка %d при объявлении сокета ',
[WSAGetLastError]);
CloseSocket(ServerSocket);
end
else
begin
ret:=listen(ServerSocket,5);
If ret=SOCKET_ERROR then
begin
ShowMessageFmt('Ошибка %d при вызове listen ',[WSAGetLastError]);
CloseSocket(ServerSocket);
end
else
begin
size_addr:=Sizeof(addr_client);
ClientSocket:=accept(ServerSocket,@addr_client,@size_addr);
If ClientSocket=SOCKET_ERROR then
begin
ShowMessageFmt('Ошибка %d при вызове accept ',[WSAGetLastError]);
CloseSocket(ServerSocket);
end
else
begin
ZeroMemory(@bufr,sizeof(bufr));
// Получение данных от клиента
ret:=recv(ClientSocket,bufr,sizeof(bufr),0);
If ret=SOCKET_ERROR then
begin
ShowMessageFmt('Ошибка %d при получении данных ',
[WSAGetLastError]);
CloseSocket(ServerSocket);
end
else
begin
// Формирование сообщения msgstring для вывода на экран
StrCopy(@msgstring,'Получено сообщение: ');
StrCat(@msgstring,@bufr);
StrCat(@msgstring,' от ');
StrCat(@msgstring,inet_ntoa(addr_client.sin_addr));
ShowMessage(msgstring);
end;
StrCopy(@bufs,@bufr);
// Пересылка эхо-ответа клиенту
ret:=send(ClientSocket,bufs,sizeof(bufs),0);
If ret=SOCKET_ERROR then
begin
ShowMessageFmt('Ошибка %d при передаче данных ',
[WSAGetLastError]);
CloseSocket(ServerSocket);
end;
end;
// закрытие сокета
CloseSocket(ServerSocket);
end;
end;
end;
end;
WSACleanup;
end;
end;
Для события OnClick командной кнопки «Выход из программы» запишите следующий программный код:
procedure TForm1.Button2Click(Sender: TObject);
begin
Form1.Close;
end;
Откомпилируйте созданное приложение.
