UNIX: разработка сетевых приложений
UNIX: разработка сетевых приложений читать книгу онлайн
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
26.6. Веб-клиент и одновременное соединение (продолжение)
Вернемся к нашему примеру с веб-клиентом из раздела 16.5 и перепишем его с использованием потоков вместо неблокируемой функции
connectconnectВ листинге 26.7 показана первая часть нашей программы, глобальные переменные и начало функции
mainЛистинг 26.7. Глобальные переменные и начало функции main
//threads/web01.c 1 #include "unpthread.h" 2 #include <thread.h> /* потоки Solaris */ 3 #define MAXFILES 20 4 #define SERV "80" /* номер порта или имя службы */ 5 struct file { 6 char *f_name; /* имя файла */ 7 char *f_host; /* имя узла или IP-адрес */ 8 int f_fd; /* дескриптор */ 9 int f_flags; /* F_xxx ниже */10 pthread_t f_tid; /* идентификатор потока */11 } file[MAXFILES];12 #define F_CONNECTING 1 /* функция connect () в процессе выполнения */13 #define F_READING 2 /* функция connect() завершена; выполняется считывание */14 #define F_DONE 4 /* все сделано */15 #define GET_CMD "GET %s HTTP/1.0rnrn"16 int nconn, nfiles, nlefttoconn, nlefttoread;17 void *do_get_read(void*);18 void home_page(const char*, const char*);19 void write_get_cmd(struct file*);20 int21 main(int argc, char **argv)22 {23 int i, n, maxnconn;24 pthread_t tid;25 struct file *fptr;26 if (argc < 5)27 err_quit("usage: web <#conns> <IPaddr> <homepage> file1 ...");28 maxnconn = atoi(argv[1]);29 nfiles = min(argc - 4, MAXFILES);30 for (i = 0; i < nfiles; i++) {31 file[i].f_name = argv[i + 4];32 file[i].f_host = argv[2];33 file[i].f_flags = 0;34 }35 printf("nfiles = %dn", nfiles);36 home_page(argv[2], argv[3]);37 nlefttoread = nlefttoconn = nfiles;38 nconn = 0;1-16<thread.h><pthread.h>10file_tidselectmaxfd36home_pageЛистинг 26.8. Основной рабочий цикл потока main
//threads/web01.c39 while (nlefttoread > 0) {40 while (nconn < maxnconn && nlefttoconn > 0) {41 /* находим файл для считывания */42 for (i = 0; i < nfiles; i++)43 if (file[i].f_flags == 0)44 break;45 if (i == nfiles)46 err_quit("nlefttoconn = %d but nothing found", nlefttoconn);47 file[i].f_flags = F_CONNECTING;48 Pthread_create(&tid, NULL, &do_get_read, &file[i]);49 file[i].f_tid = tid;50 nconn++;51 nlefttoconn--;52 }53 if ((n = thr_join(0, &tid, (void**)&fptr)) != 0)54 errno = n, err_sys("thr_join error");55 nconn--;56 nlefttoread--;57 printf("thread id %d for %s donen", tid, fptr->f_name);58 }59 exit(0);60 }40-52nconnmaxconndo_get_readfile
