使用select的TCP和UDP服务器

使用select函数的TCP和UDP回射服务器程序

#include "unp.h"

int main(int argc, char **argv){
    int listenfd, connfd, udpfd, nready, maxfdp1;
    char mesg[MAXLINE];
    pid_t childpid;
    fd_set rset;
    ssize_t n;
    socklen_t len;
    const int on = 1;
    struct sockaddr_in cliaddr, servaddr;
    void sig_chld(int);        //创建TCP的监听
    
    listenfd = socket(AF_INET,SOCK_STREAM,0);
    bzero(&servaddr,sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(SERV_PORT);

    setsockopt(listenfd,SOL_SOCKET,SO_REUSERADDR,&on,sizeof(on));
    bind(listenfd, LISTENQ);
    
    udpfd = socket(AF_INET, SOCK_DGRAM, 0);
    bzero(&servaddr,sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(SERV_PORT);

    bind(udpfd, (SA*) &servaddr, sizeof(servaddr));

    signal(SIGCHLD, sig_chld);
    FD_ZERO(&rset);
    maxfdpl = max(listenfd,udpfd)+1;
    for(;;){
        FD_SET(listenfd,&rset);
        FD_SET(udpfd,&rset);
        if((nready = select(maxfdpl, &rset, NULL, NULL, NULL)) < 0){
            if(errno == EINTR)
                continue;
            else
                err_sys("select error");
        }

        if(FD_ISSET(listenfd, &rset)){
            len = sizeof(cliaddr);
            connfd = accept(listenfd,(SA *) &cliaddr, &len);
            if((childpid = fork()) == 0){    //子进程
                close(listenfd);             //关闭监听套接字
                str_echo(connfd);            //处理请求
                exit(0);
            }
            close(connfd);                   //关闭父连接套接字
        }
        
        if(FD_ISSET(udpfd, &rset)){
            len = sizeof(cliaddr);
            n = recvfrom(udpfd, mesg, MAXLINE, 0, (SA*) &cliaddr, &len);

            sendto(udpfd,mesg, n, 0, (SA*) &cliaddr, 0);
        }
    }
}
发布了90 篇原创文章 · 获赞 6 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_37160123/article/details/103969917