}

/* Читать один поступивший буфер, распечатать некоторую информацию

 * и завершить работу. */

#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 между клиентом и сервером. Вызовы socket() и bind() быстро выполняются и немедленно возвращают ответ. Вызов recvfrom предполагает режим блокирования по умолчанию, который можно изменить на неблокированный (т.е. асинхронный) режим.

Рис. 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);

  }

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату