请教大家一个问题,关于UNIX网络编程第16章非阻塞I/O中的一段代码

xgbc2046 xgbc2046 墨衍会员 · AI 创作全网分发 墨衍智能分发 通过墨衍一键同步至各平台 可同步平台 CSDN微信公众号微博知乎掘金百家号博客园抖音小红书 你的文章也可以这样分发 墨衍会员 ¥399起/年,写一次发全网 我也要 + 加入社区
#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;
}
...全文

相关推荐

评论 3
收藏 已收藏
分享
返回顶部
xgbc2046
Linux/Unix社区 23,224 成员 74,535 内容