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

相关推荐
0+1114 小时前
Linux --从 poll 到 epoll多路转接
linux·服务器·1024程序员节
青瓦梦滋5 小时前
WebSocket协议
linux·服务器·网络·c++·websocket·网络协议·http
桌面运维家5 小时前
旧电脑跑不动课程软件,VDI云桌面怎样接着用?
运维·服务器·虚拟化·pve·vdi·云桌面
zhang133830890755 小时前
传统机械三杯式风速传感器易磨损冻堵?CG-88金属超声波风速风向传感器给出免运维方案
运维·服务器·网络·人工智能·自动化
知已难寻6 小时前
第 2 篇 · 云的地基:服务器、存储、网络三大基础设施
运维·服务器·网络·云原生·云计算·负载均衡·1024程序员节
今天重构了吗8 小时前
Linux 上 rm -rf 删错了能找回吗
运维·服务器
Smoothcloud润云9 小时前
GPU远程纳管安全吗?最小权限、网络边界与日志审计实战
服务器·网络·人工智能·安全·gpu算力·gpu
ai大模型-探索者9 小时前
Function Call与MCP(区别、联系与实战)
java·服务器·网络
略略略咯咯9 小时前
啊啊啊啊啊
java·服务器·数据库
木子欢儿10 小时前
Debian 13 + vsftpd 搭建FTP服务
linux·服务器·前端·网络·debian