Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
лабораторная работа8.doc
Скачиваний:
2
Добавлен:
01.04.2025
Размер:
143.87 Кб
Скачать

3. Схема работы сервера и клиента с предварительным установлением связи

Сервер

Клиент

Создать сокет1 ;

Связать сокет1 с адресом ;

Уведомить систему о готовности принимать запросы на установление связи ;

while (1)

{ Извлечь запрос из очереди запросов на установление связи и получить новый сокет2 для обмена информацией с клиентом, пославшим запрос ;

Породить дочерний процесс для взаимодействия через сокет2 с клиентом, пославшим запрос ;

}

Создать сокет :

Послать запрос

на установление предварительного соединения ;

Осуществлять коммуникации с

сервером ;

4. Пример сервера и клиента

Приложение клиент устанавливает соединение с сервером, посылает ему сообщение, получает ответ от сервера и выводит его на экран.

Программный код клиента.

#include <stdio.h>

#include <strings.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

#define PORT 1125

int main()

{ int sd,num ; //sd – дескриптор сокета

char buf[60] ; //для посылки и получения данных

sprintf(buf,"Привет!") ;

struct sockaddr_in saddr ; //адрес сервера

bzero(&saddr, sizeof(saddr)) ; //очистить адрес

saddr.sin_family=AF_INET ;

saddr.sin_port = PORT ;

saddr.sin_addr.s_addr=INADDR_ANY ;//клиент и сервер выполняются на одной машине

sd=socket(AF_INET, SOCK_STREAM, 0) ;

if (sd<0) { fprintf(stdout, "\nНевозможно создать сокет") ; return 0 ; }

if ( connect(sd, (struct sockaddr *)&saddr, sizeof(saddr))<0 )

{ fprintf(stdout,"\nНевозможно установить соединение с сервером") ; return 0 ;}

num = send(sd,buf,sizeof(buf),0) ; //послать сообщение серверу

if (num<0) { fprintf(stdout,"\nОшибка") ; return 0 ;}

num=recv(sd,buf,60,0) ; //получить ответ от сервера

if (num<0) { fprintf(stdout,"\nОшибка") ; return 0 ; }

else fprintf(stdout,"\nПолучен ответ %s",buf) ;

return 1 ;

}

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

Программный код сервера.

#include <stdio.h>

#include <strings.h>

#include <unistd.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

#define PORT 1125

int main()

{ int sd,ns ; //sd – дескриптор сокета

//saddr – адрес сервера, caddr – для записи адресов клиентов

struct sockaddr_in saddr, caddr ;

char buf[60] ; //для посылки и получения данных

sd=socket(AF_INET,SOCK_STREAM,0) ;

if (sd<0) { fprintf(stdout,"\nНевозможно создать сокет ") ; return 0 ;}

else fprintf(stdout,"\nСокет создан ") ;

bzero(&saddr, sizeof(saddr)) ; //очистить адрес

saddr.sin_family = AF_INET ;

saddr.sin_addr.s_addr = INADDR_ANY ;

saddr.sin_port=PORT ;

if ( bind(sd, (struct sockaddr *)&saddr, sizeof(saddr))<0 )

{ fprintf(stdout,"\nНевозможно связать сокет с адресом") ; return 0 ;}

if ( listen(sd,3)<0 )

{ fprintf(stdout,"\nОшибка вызова listen() ") ; return 0 ; }

else fprintf(stdout,"\nСервер запущен") ;

while(1)

{ bzero(&caddr,sizeof(caddr)) ; //очистить адрес

int sd2,pid ; // sd2 – дескриптор сокета для коммуникации с клиентом

socklen_t addrlen ; //для получения размера адреса клиента

sd2=accept(sd, (struct sockaddr *)&caddr, &addrlen) ;

if (sd2>0) { fprintf(stdout,"\nПринят запрос на установление связи ") ;

pid=fork() ;

if (pid<0) { fprintf(stdout,"\nНевозможно создать процесс") ; continue ; }

if (pid==0) //дочерний процесс осуществляет коммуникации с клиентом

{ int num ;

close(sd) ; //дочернему процессу не нужен дескриптор sd

num=recv(sd2,buf,60,0) ;

if (num<0) { fprintf(stdout,"\nОшибка чтения ") ; return 0 ; }

char buf2[60] ;

sprintf(buf2,"Ответ сервера %s",buf) ;

num=send(sd2,buf2,sizeof(buf2),0) ;

if (num<0) { fprintf(stdout,"\nОшибка записи ") ; return 0 ; }

return 1 ;

}

close(sd2) ; } ; //родительскому процессу не нужен дескриптор sd2

}

return 1 ;

}