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

相关推荐
进击的_鹏3 小时前
从零开始的 Redis 学习
服务器·数据库·c++·redis·缓存
实心儿儿3 小时前
Linux —— 传输层协议TCP
linux·服务器·tcp/ip
4311媒体网4 小时前
帝国CMS网站自定义搭建技巧
服务器·开发语言·前端
Dachui_11224 小时前
企业内网大模型公网访问方案:Ollama + OpenWebUI + ZeroNews 实战部署记录
运维·服务器·安全·远程工作·内网穿透
2401_890603404 小时前
Linux 进程控制
linux·运维·服务器
啦啦啦啦啦zzzz5 小时前
时间轮定时器
linux·服务器·网络·c++·定时器
一只旭宝5 小时前
预约系统版本2(pyhton+flask可视化版本)
服务器·数据库·c++·笔记·python·flask
丰锋ff7 小时前
初识Linux操作系统
linux·运维·服务器
嵌入式小能手7 小时前
飞凌嵌入式ElfBoard-Shell脚本编写基础-特殊变量
linux·运维·服务器
SWAGGY..7 小时前
【C++初阶】:(15)模板进阶--从非类型参数到模板特化与分离编译
java·服务器·前端