Unix Network Programming Episode 105

复制代码
#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);

    flags=Fcntl(fd, F_GETFL, 0);
    Fcntl(fd, F_SETFL, flags|O_NONBLOCK);

    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);
        FD_SET(fd, &wset);

        if(fd>maxfd)
            maxfd=fd;
    }
    else if(n>=0)
    {
        write_get_cmd(fptr);
    }
}

Initiate nonblocking connect

复制代码
#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;

    FD_SET(fptr->f_fd, &rset);
    if(fptr->f_fd>maxfd)
    {
        maxfd=fptr->f_fd;
    }
}

Send an HTTP GET command to the server

复制代码
    while(nlefttoread>0)
    {
        while(nconn<maxnconn&&nlefttoconn>0)
        {
            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);
                    }
                    printf("connection established fro %s\n", file[i].f_name);
                    FD_CLR(fd, &wset);
                    write_get_cmd(&file[i]);
                }
                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;
                        FD_CLR(fd, &rset);
                        nconn--;
                        nlefttoread--;
                    }
                }
                else
                {
                    printf("read %d bytes from %s\n", n, file[i].f_name);
                }
        }
    }

    return 0;
}

Main loop of main function

相关推荐
大树886 小时前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
小宇宙Zz7 小时前
Maven依赖冲突
java·服务器·maven
古城小栈8 小时前
Unix 与 Linux 异同小叙
linux·服务器·unix
程序猿阿伟9 小时前
《Chrome离线扩展安装的底层逻辑与场景落地指南》
服务器·网络·chrome
凡人叶枫9 小时前
Effective C++ 条款42:了解 typename 的双重意义
java·linux·服务器·c++
AC赳赳老秦10 小时前
用 OpenClaw 搭建服务器故障应急响应系统,自动处理 80% 常见运维故障
android·运维·服务器·python·rxjava·deepseek·openclaw
java_cj10 小时前
深入kube-apiserver认证机制:从Bearer Token到mTLS的完整认证链解析
linux·运维·服务器·云原生·容器·kubernetes
lsyeei10 小时前
linux 系统目录详解
linux·运维·服务器
森G10 小时前
75、服务器源码解析---------云视频服务项目
linux·服务器·网络·c++·qt
张飞飞飞飞飞10 小时前
Tmux命令使用教程
linux·服务器·ubuntu