В языке С команда fork создает новый дочерний процесс, который наследует все дескрипторы ввода/вывода родительской программы, а также имеет доступ к sockMain и sockClient. Операционная система отслеживает количество процессов, имеющих доступ к socket.
Соединение закрывается, когда последний обращающийся к socket процесс вызывает close.
Когда дочерний процесс закрывает sockMain, родительский процесс все еще имеет доступ к socket.
7. close(sockClient);
Этот вызов выполняется из родительской части программы. Когда родительский процесс закрывает sockClient, дочерний процесс все еще имеет доступ к socket.
По умолчанию вызов recv блокированный. Функции fcntl или iocntl позволяют изменить статус socket на неблокированный режим.
После получения данных дочерним процессом и вывода сообщения на печать, доступ к sockClient закрывается. Это заставит соединение перейти в фазу закрытия.
21.7 Клиентская программа TCP
Клиент соединяется с сервером, посылает одно сообщение, и далее работа программы завершается (фрагменты программы рассматриваются в следующем разделе). Для запуска программы конечный пользователь должен ввести имя хоста сервера, номер порта и сообщение, которое будет послано на этот сервер. Например:
tcpclient pltim.cs.yale.edu 1356 hello
/* tcpclient.с
* Перед запуском клиента должен быть запущен сервер. Производится
* поиск порта сервера. Для запуска клиента нужно ввести:
* tcpclient имя_хоста порт сообщение */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <errno.h>
main(argc, argv) /* Клиентская программа имеет входные аргументы. */
int argc;
char* argv[];
{
int sock;
struct sockaddr_in servAddr;
struct hostent *hp, *gethostbyname;
/* Аргументами будут 0:имя_программы, 1:имя_хоста, 2:порт, 3:сообщение */
if (argc < 4)
{
printf("ВВЕСТИ tcpclient
имя_хоста порт сообщение\n");
exit(1);
}
/* 1. Создание TCB. */
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("He могу получить socket\n");
exit(1);
}
/* 2. Заполнить поля адреса и порта сервера в servAddr.
* Сначала заполнить нулями адресную структуру. Затем получить IP-адрес
* для данного имени хоста и ввести его в адресную структуру.
* Наконец ввести номер порта, взяв его из argv[2]. */
Клиент создает блок управления пересылкой ("socket") так же, как это делал сервер.
2. Сервер должен инициализировать адресную структуру для использования в bind.
Эта структура содержит локальный IP-адрес и номер порта сервера. Клиент также инициализирует адресную структуру, хранящую те же сведения. Эта структура будет использоваться в вызове connect для указания точки назначения.