UNIX: разработка сетевых приложений
UNIX: разработка сетевых приложений читать книгу онлайн
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
connfd = Accept(listenfd, cliaddr, &len); Pthread_create(&tid, NULL, &doit, &connfd); }}static void* doit(void *arg) { int connfd; connfd = *((int*)arg); Pthread_detach(pthread_self()); str_echo(connfd); /* та же функция, что и прежде */ Close(connfd); /* мы закончили с присоединенным сокетом */ return(NULL);}С точки зрения ANSI С здесь все в порядке: мы гарантированно можем преобразовать целочисленный указатель к типу
void*В главном потоке имеется одна целочисленная переменная
connfdaccept■ Функция
acceptconnfdpthread_createconnfdpthread_create■ Создается новый поток, и начинает выполняться функция
doit■ Готово другое соединение, и главный поток снова начинает выполняться (прежде, чем начнется выполнение вновь созданного потока). Завершается функция
acceptconnfdpthread_createХотя созданы два новых потока, оба они будут работать с одним и тем же последним значением переменной
connfdconnfdconnfdpthread_createВ листинге 26.3 показано более удачное решение описанной проблемы.
Листинг 26.3. Эхо-сервер TCP, использующий потоки с более переносимой передачей аргументов
//threads/tcpserv02.c 1 #include "unpthread.h" 2 static void *doit(void*); /* каждый поток выполняет эту функцию */ 3 int 4 main(int argc, char **argv) 5 { 6 int listenfd, *iptr; 7 thread_t tid; 8 socklen_t addrlen, len; 9 struct sockaddr *cliaddr;10 if (argc == 2)11 listenfd = Tcp_listen(NULL, argv[1], &addrlen);12 else if (argc == 3)13 listenfd = Tcp_listen(argv[1], argv[2], &addrlen);14 else15 err_quit("usage: tcpserv01 [ <host> ] <service or port>");16 cliaddr = Malloc(addrlen);17 for (;;) {18 len = addrlen;19 iptr = Malloc(sizeof(int));20 *iptr = Accept(listenfd, cliaddr, &len);21 Pthread_create(&tid, NULL, &doit, iptr);22 }23 }24 static void*25 doit(void *arg)26 {27 int connfd;28 connfd = *((int*)arg);29 free(arg);30 Pthread_detach(pthread_self());31 str_echo(connfd); /* та же функция, что и раньше */32 Close(connfd); /* мы закончили с присоединенным сокетом */33 return (NULL);34 }17-22acceptmalloc28-29freeИсторически функции
mallocfree
