请教大家一个问题,关于UNIX网络编程第16章非阻塞I/O中的一段代码
#include "web.h"
int
main(int argc, char **argv)
{
int i, fd, n, maxnconn, flags, error;
char buf[MAXLINE];
fd_set rs, ws;
if (argc < 5)
err_quit("usage: web <#conns> <hostname> <homepage> <file1> ...");
maxnconn = atoi(argv[1]);
nfiles = min(argc - 4, MAXFILES);
for (i = 0; i < nfiles; i++) {
file[i].f_name = argv[i + 4];
file[i].f_host = argv[2];
file[i].f_flags = 0;
}
printf("nfiles = %d\n", nfiles);
home_page(argv[2], argv[3]);
FD_ZERO(&rset);
FD_ZERO(&wset);
maxfd = -1;
nlefttoread = nlefttoconn = nfiles;
nconn = 0;
/* end web1 */
/* include web2 */
while (nlefttoread > 0) {
while (nconn < maxnconn && nlefttoconn > 0) {
/* 4find a file to read */
for (i = 0 ; i < nfiles; i++)
if (file[i].f_flags == 0)
break;
if (i == nfiles)
err_quit("nlefttoconn = %d but nothing found", nlefttoconn);
start_connect(&file[i]);
nconn++;
nlefttoconn--;
}
rs = rset;
ws = wset;
n = Select(maxfd+1, &rs, &ws, NULL, NULL);
for (i = 0; i < nfiles; i++) {
flags = file[i].f_flags;
if (flags == 0 || flags & F_DONE)
continue;
fd = file[i].f_fd;
if (flags & F_CONNECTING &&
(FD_ISSET(fd, &rs) || FD_ISSET(fd, &ws))) {
n = sizeof(error);
if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &n) < 0 ||
error != 0) {
err_ret("nonblocking connect failed for %s",
file[i].f_name);
}
/* 4connection established */
printf("connection established for %s\n", file[i].f_name);
FD_CLR(fd, &wset); /* no more writeability test */
write_get_cmd(&file[i]);/* write() the GET command */
} else if (flags & F_READING && FD_ISSET(fd, &rs)) {
if ( (n = Read(fd, buf, sizeof(buf))) == 0) {
printf("end-of-file on %s\n", file[i].f_name);
Close(fd);
file[i].f_flags = F_DONE; /* clears F_READING */
FD_CLR(fd, &rset);
nconn--;
nlefttoread--;
} else {
printf("read %d bytes from %s\n", n, file[i].f_name);
}
}
}
}
exit(0);#include "web.h"
void
start_connect(struct file *fptr)
{
int fd, flags, n;
struct addrinfo *ai;
ai = Host_serv(fptr->f_host, SERV, 0, SOCK_STREAM);
fd = Socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
fptr->f_fd = fd;
printf("start_connect for %s, fd %d\n", fptr->f_name, fd);
/* 4Set socket nonblocking */
flags = Fcntl(fd, F_GETFL, 0);
Fcntl(fd, F_SETFL, flags | O_NONBLOCK);
/* 4Initiate nonblocking connect to the server. */
if ( (n = connect(fd, ai->ai_addr, ai->ai_addrlen)) < 0) {
if (errno != EINPROGRESS)
err_sys("nonblocking connect error");
fptr->f_flags = F_CONNECTING;
FD_SET(fd, &rset); /* select for reading and writing */
FD_SET(fd, &wset);
if (fd > maxfd)
maxfd = fd;
} else if (n >= 0) /* connect is already done */
write_get_cmd(fptr); /* write() the GET command */
}#include "web.h"
void
write_get_cmd(struct file *fptr)
{
int n;
char line[MAXLINE];
n = snprintf(line, sizeof(line), GET_CMD, fptr->f_name);
Writen(fptr->f_fd, line, n);
printf("wrote %d bytes for %s\n", n, fptr->f_name);
fptr->f_flags = F_READING; /* clears F_CONNECTING */
FD_SET(fptr->f_fd, &rset); /* will read server's reply */
if (fptr->f_fd > maxfd)
maxfd = fptr->f_fd;
}
...全文
相关推荐
Unix 系统和网络编程16-7答案完整版
**I/O操作**:Unix提供了多种I/O模型,如同步I/O、异步I/O和缓冲I/O。文件描述符的概念,以及`read`, `write`, `open`, `close`等函数的使用是基础内容。
Unix网络编程及配套源代码
通过编写简单的客户端和服务器程序,可以理解数据在网络中的传输过程,熟悉套接字API的使用,并了解网络编程中的常见问题,如阻塞与非阻塞I/O、同步与异步模型、错误处理等。
UNIX网络编程 第2卷 进程间通信.pdf(带书签)
第16章到第19章则分别介绍了非阻塞I/O、ioctl操作、路由套接口和密钥管理套接口等高级编程技术。第20章到第25章则深入讨论了广播、多播、带外数据和信号驱动I/O等网络通信的高级特性。
Unix网络编程Code
**多线程和异步I/O**:在处理多个客户端连接时,服务器可能使用多线程或多进程模型,或者利用select()、poll()、epoll()等机制实现异步I/O,提高并发性能。6.
Unix系统和网络编程第十六章16-8答案
**服务器模型**:可能探讨了常见的服务器模型,如单线程服务器、多线程服务器、异步非阻塞I/O服务器(如epoll模型)以及事件驱动服务器(如使用select或poll函数)。7.


