}
/* Читать один поступивший буфер, распечатать некоторую информацию
* и завершить работу. */
#define BUFLEN 81
int doTask(sockClient)
int sockClient;
{
char buf[BUFLEN];
int msgLength;
/* 8. Опустошение буфера и вызов recv
* для получения сообщения от клиента. */
bzero(buf, BUFLEN);
if ((msgLength = recv(sockClient,buf, 80, 0)) < 0) {
perror('Неверное получение.' );
exit(1);
}
printf('SERVER: Socket для клиента %d
', sockClient);
printf('SERVER: Длина сообщения %d
', msgLength);
printf('SERVER: Сообщение: %s
', buf);
}
21.9 Интерфейс программирования socket для UDP
Мы познакомились с наиболее общим интерфейсом программирования TCP. Теперь рассмотрим программирование сервера и клиента UDP. На рис. 21.3 показана схема диалога UDP между клиентом и сервером. Вызовы
Рис. 21.3. Типичные программные вызовы в socket UDP
21.10 Программа сервера UDP
Показанная ниже программа создает socket для UDP, связывает вызов с портом, а затем получает и распечатывает сообщения, которые посылаются на этот порт:
/* udpserv.c
* Для запуска программы ввести 'udpserv'.
*
* Сначала включить стандартные заголовочные файлы. */
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
#include <netdb.h>
#include <errno.h>
#define BUFLEN 81
main() {
int sockMain, addrLength, msgLength;
struct sockaddr_in servAddr, clientAddr;
char buf[BUFLEN];
/* 1. Создать socket для UDP. */
if ((sockMain = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror('Сервер не может открыть socket для UDP.');
exit(1);
}
/* 2. Ввести информацию в структуру данных, используемую для хранения локальных
* IP-адресов и порта. Возложить на bind получение свободных портов. */
bzero((char *)&servAddr, sizeof(servAddr));
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
servAddr.sin_port = 0;
/* 3. Вызвать bind, которая запишет номер используемого порта
* в TCB. */
if (bind(sockMain, &servAddr, sizeof(servAddr))) {
perror('Вызов bind от сервера неудачен.');
exit(1);
}
/* 4. Извлекаем номер порта и используем функцию
* getsockname() для копирования порта в servAddr. */
addrLength = sizeof(servAddr);
if ( getsockname(sockMain, &servAddr, &addrLength)) {
perror(Вызов getsockname неудачен.');
exit(1);
}
printf('SERVER: Номер порта is %d
', ntohs(servAddr.sin_port));
/* 5. Бесконечный цикл ожидания сообщений от клиентов. */
for (;;) {
addrLength = sizeof(clientAddr);
bzero(buf, BUFLEN);
if ((msgLength = recvfrom(sockMain, buf, BUFLEN, 0, &clientAddr, &addrLength)) < 0) {
perror('Плохой socket клиента.');
exit(1);
}