Эффективное программирование TCP-IP

       

Источник и приемник на базе UDP


В случае UDP клиент посылает нефиксированное количество датаграмм, которые сервер читает, подсчитывает и отбрасывает. Исходный текст клиента приведен в листинге 2.16.

Листинг 2.16. UDP-клиент, посылающий произвольное число датаграмм

1    #include   "etcp.h"

2    int main( int argc, char **argv )

3    {

4    struct sockaddr_in peer;

5    SOCKET s;

6    int rc;

7    int datagrams;

8    int dgramsz = 1440;

9    char buf[ 1440 ];

10   INIT();

11   datagrams = atoi( argv[ 2 ] );



12   if ( argc > 3 )

13     dgramsz = atoi( argv [ 3 ] );

14   s = udp_client( argv[ 1 ], "9000", &peer );

15   while ( datagrams-- > 0 )

16   {

17     rc = sendto( s, buf, dgramsz, 0,

18      ( struct sockaddr * )&peer, sizeof( peer ) );

19     if ( rc <= 0 )

20      error( 0, errno, "ошибка вызова sendto" );

21   }

22   sendto( s, "", 0, 0,

23     ( struct sockaddr * )&peer, sizeof( peer ) );

24   EXIT( 0 );

25   }

10-14 Читаем из командной строки количество посылаемых датаграмм и их размер (второй параметр необязателен). Подготавливаем в переменной peer UDP-сокет с адресом сервера. Вопреки совету 29 номер порта 9000 жестко «зашит» в код.

15-21 Посылаем указанное количество датаграмм серверу.

22-23 Посылаем серверу последнюю датаграмму, содержащую нулевой байт. Для сервера она выполняет роль конца файла.

Текст сервера в листинге 2.17 еще проще.

Листинг 2.17. Приемник датаграмм

1    #include "etcp.h"

2    int  main( int argc, char **argv   )

3    {

4    SOCKET s;

5    int rc;

6    int datagrams = 0;

7    int rcvbufsz = 5000 * 1440;

8    char buf[ 1440 ];

9    INIT();

10   s = udp_server( NULL, "9000" );

11   setsockopt ( s, SOL_SOCKET, SO_RCVBUF,

12     ( char * )&rcvbufsz, sizeof( int ) ) ;

13   for ( ;; )

14   {

15     rc = recv( s, buf, sizeof( buf ), 0 );

16     if ( rc <= 0 )

17      break;

18     datagrams++;

19   }

20   error( 0, 0, "получено датаграмм: %d \n", datagrams );

21   EXIT( 0 ) ;

22   }

10 Подготавливаем сервер к приему датаграмм из порта 9000 с любого интерфейса.

11-12 Выделяем память для буфера на 5000 датаграмм длиной до 1440 байт.

Примечание: Здесь устанавливается размер буфера 7200000 байт, но нет гарантии, что операционная система выделит столько памяти. Хост, работающий под управлением системы BSD, выделил буфер размером 41600 байт. Этим объясняется потеря датаграмм, которая будет рассмотрена далее.

13-19 Читаем и подсчитываем датаграммы, пока не придет пустая датаграмма или не произойдет ошибка.

20 Выводим число полученных датаграмм на stdrerr.



Содержание раздела