zoukankan      html  css  js  c++  java
  • 【网络编程】学习笔记04 server端和client代码

    Server端:

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<unistd.h>
    #include<errno.h>
    #include<pthread.h>
    #include<ctype.h>
    #include<sys/socket.h>
    #include<arpa/inet.h>
    
    #define SERV_PORT 9527
    
    void sys_err(const char *str)
    {
        perror(str);
        exit(1);
    }
    
    int main(int argc,char *argv[])
    {
        int lfd = 0,cfd = 0;
        int ret,i;
        char buf[BUFSIZ],client_IP[BUFSIZ];
    
        struct sockaddr_in serv_addr,clit_addr;
        socklen_t clit_addr_len;
    
        serv_addr.sin_family = AF_INET;
        serv_addr.sin_port = htons(SERV_PORT);
        serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    
    
        lfd = socket(AF_INET,SOCK_STREAM,0);
        if(lfd==-1){
            sys_err("socket error");
        }
    
        bind(lfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr));
    
        listen(lfd,128);
    
        clit_addr_len = sizeof(clit_addr);
    
        cfd = accept(lfd,(struct sockaddr *)&clit_addr,&clit_addr_len);
        if(cfd==-1){
            sys_err("accept error");
        }
        printf("client ip:%s port:%d\n",
                inet_ntop(AF_INET, &clit_addr.sin_addr.s_addr,client_IP,sizeof(client_IP)),
                ntohs(clit_addr.sin_port));
    
        while(1){
            ret = read(cfd,buf,sizeof(buf));
    
            for(i=0;i<ret;i++)
                buf[i]=toupper(buf[i]);
            write(STDOUT_FILENO,buf,ret);
        }
        close(lfd);
        close(cfd);
        return 0;
    }
    View Code

    Client端:

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<unistd.h>
    #include<arpa/inet.h>
    #include<sys/socket.h>
    
    #define SERV_PORT 9527
    
    void sys_err(const char *str)
    {
        perror(str);
        exit(1);
    }
    
    int main(int argc,char *argv[])
    {
        int cfd;
        int conter=10;
        char buf[BUFSIZ];
            
        struct sockaddr_in serv_addr;
        serv_addr.sin_family = AF_INET;
        serv_addr.sin_port = htons(SERV_PORT);
    
        inet_pton(AF_INET,"127.0.0.1",&serv_addr.sin_addr.s_addr);
    
        cfd = socket(AF_INET,SOCK_STREAM,0);
        if(cfd==-1)
            sys_err("socket error");
    
        int ret = connect(cfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr));
        if(ret!=0)
            sys_err("connect error");
    
        while(conter--)
        {
            ret = read(STDIN,buf,sizeof(buf));
            write(cfd,buf,ret)
            write(STDOUT_FILENO,buf,ret);
            sleep(1);
        }
        close(cfd);
    
        return 0;
    }
    View Code

    运行的时候,开2个窗口,一个窗口跑server端,./server即可,另一个跑client端,./client即可。注意要先编译。

    多进程+回收子进程(信号捕捉杀僵尸进程)版server:

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<unistd.h>
    #include<errno.h>
    #include<signal.h>
    #include<pthread.h>
    #include<sys/socket.h>
    #include<arpa/inet.h>
    #include<ctype.h>
    #include<sys/wait.h>
    #include<sys/types.h>
    
    #define SRV_PORT 9999
    
    void catch_child(int signum)
    {
        while(waitpid(0,NULL,WNOHANG)>0);
        return ;
    }
    int main(int argc,char *argv[])
    {
        int lfd,cfd;
        pid_t pid;
        struct sockaddr_in srv_addr,clt_addr;
        socklen_t clt_addr_len;
        char buf[BUFSIZ];
        int ret,i;
    
        memset(&srv_addr,0,sizeof(srv_addr));
    
        srv_addr.sin_family = AF_INET;
        srv_addr.sin_port = htons(SRV_PORT);
        srv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    
        lfd = socket(AF_INET,SOCK_STREAM,0);
    
        bind(lfd,(struct sockaddr *)&srv_addr,sizeof(srv_addr));
    
        listen(lfd,128);
    
        clt_addr_len = sizeof(clt_addr);
    
        while(1){
    
            cfd = accept(lfd,(struct sockaddr *)&clt_addr ,&clt_addr_len);
            pid = fork();
            if(pid == 0){
                close(lfd);
                break;    
            }
            else if(pid > 0){
                struct sigaction act;
                act.sa_handler = catch_child;
                sigemptyset(&act.sa_mask);
                act.sa_flags = 0;
                ret = sigaction(SIGCHLD,&act,NULL);
                
                close(cfd);
            }
        }
    
        if(pid == 0){
            for(;;){
                ret = read(cfd, buf ,sizeof(buf));
                if(ret == 0){
                    close(cfd);
                    exit(1);
                }
    
                for(i=0;i<ret;i++)
                    buf[i]=toupper(buf[i]);
                write(cfd,buf,ret);
                write(STDOUT_FILENO,buf,ret);
            }
        }
        return 0;
    }
    View Code

    多进程+回收子进程+端口复用版server:

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<unistd.h>
    #include<errno.h>
    #include<signal.h>
    #include<pthread.h>
    #include<sys/socket.h>
    #include<arpa/inet.h>
    #include<ctype.h>
    #include<sys/wait.h>
    #include<sys/types.h>
    
    #define SRV_PORT 9999
    
    void catch_child(int signum)
    {
        while(waitpid(0,NULL,WNOHANG)>0);
        return ;
    }
    int main(int argc,char *argv[])
    {
        int lfd,cfd;
        pid_t pid;
        struct sockaddr_in srv_addr,clt_addr;
        socklen_t clt_addr_len;
        char buf[BUFSIZ];
        int ret,i;
    
        memset(&srv_addr,0,sizeof(srv_addr));
    
        srv_addr.sin_family = AF_INET;
        srv_addr.sin_port = htons(SRV_PORT);
        srv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    
        lfd = socket(AF_INET,SOCK_STREAM,0);
        
        int opt=1;
        setsockopt(lfd,SOL_SOCKET,SO_REUSEADDR,(void*)&opt,sizeof(opt))
        bind(lfd,(struct sockaddr *)&srv_addr,sizeof(srv_addr));
    
        listen(lfd,128);
    
        clt_addr_len = sizeof(clt_addr);
    
        while(1){
    
            cfd = accept(lfd,(struct sockaddr *)&clt_addr ,&clt_addr_len);
            pid = fork();
            if(pid == 0){
                close(lfd);
                break;    
            }
            else if(pid > 0){
                struct sigaction act;
                act.sa_handler = catch_child;
                sigemptyset(&act.sa_mask);
                act.sa_flags = 0;
                ret = sigaction(SIGCHLD,&act,NULL);
                
                close(cfd);
            }
        }
    
        if(pid == 0){
            for(;;){
                ret = read(cfd, buf ,sizeof(buf));
                if(ret == 0){
                    close(cfd);
                    exit(1);
                }
    
                for(i=0;i<ret;i++)
                    buf[i]=toupper(buf[i]);
                write(cfd,buf,ret);
                write(STDOUT_FILENO,buf,ret);
            }
        }
        return 0;
    }
    View Code

    运用select的(可以不用写多进程)的server:

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<unistd.h>
    #include<errno.h>
    #include<pthread.h>
    #include<ctype.h>
    #include<sys/socket.h>
    #include<arpa/inet.h>
    
    #define SERV_PORT 9527
    
    void sys_err(const char *str)
    {
        perror(str);
        exit(1);
    }
    
    int main(int argc,char *argv[])
    {
        int listenfd = 0,connfd = 0;
        char buf[BUFSIZ];
    
        struct sockaddr_in serv_addr,clie_addr;
        socklen_t clie_addr_len;
        
        listenfd = socket(AF_INET,SOCK_STREAM,0);
    
        int opt = 1;
        setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
    
        memset(&serv_addr,0,sizeof(serv_addr));
        serv_addr.sin_family = AF_INET;
        serv_addr.sin_port = htons(SERV_PORT);
        serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
        bind(listenfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr));
        listen(listenfd,128);
    
        fd_set rset,allset;                 //定义读集合rset,备份集合allset
        int ret,maxfd = 0,n,i,j;
        maxfd = listenfd;                   //最大文件描述符
    
        FD_ZERO(&allset);                   //清空监听集合
        FD_SET(listenfd,&allset);           //将待监听fd添加到监听集合中
    
        while(1){
            rset = allset;                  //备份
            ret = select(maxfd+1, &rset, NULL, NULL,NULL);  //使用select监听
            
            if(FD_ISSET(listenfd,&rset)){               //listenfd满足监听读事件
                clie_addr_len = sizeof(clie_addr);
                connfd = accept(listenfd, (struct sockaddr *)&clie_addr, &clie_addr_len); //与客户端建立连接,不会阻塞
    
                FD_SET(connfd, &allset);        //将新产生的fd添加到监听集合中,监听数据读事件
                if(maxfd < connfd)              //修改maxfd
                    maxfd = connfd;
    
                if(ret == 1)                    //说明select返回值只有1个,并且是listenfd,后续无需执行
                    continue;
            }
            for(i = listenfd+1; i<=maxfd; i++){     //处理满足读事件的fd
                if(FD_ISSET(i,&rset)){              //找到满足读事件的fd
                    n = read(i,buf,sizeof(buf));
                    if(n == 0){                     //检测到客户端已经关闭连接
                        close(i);
                        FD_CLR(i,&allset);          //将关闭的fd移除出监听集合
                    }
    
                    for(j = 0; j < n;j++)
                        buf[j] = toupper(buf[j]);
    
                    write(i,buf,n);
                    write(STDOUT_FILENO,buf,n);
                }
            }
        }
        close(listenfd);
        return 0;
    }
    View Code
    前ICPC算法竞赛退役选手|现摸鱼ing
  • 相关阅读:
    重排序
    线程的生命周期状态
    并发的有序性
    并发的可见性
    并发的原子性
    Java内存模型
    缓存一致性协议MESI
    lsof
    nmap
    elastcisearch简介
  • 原文地址:https://www.cnblogs.com/Anonytt/p/15541470.html
Copyright © 2011-2022 走看看