• reuseaddr和点对点聊天


    解决绑定失败

    在测试时,经常会出现绑定错误,bind error: Address already in use
    这里只要指定一下socket的reuseaddr属性即可解决

    int on=1;
    if(setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on) <0)
        err_quit("setsockopt");
    
    bind(...)
    

    点对点

    1.本例子使用双进程,一个用于接受信息,一个用于发送消息
    2.当read(sockfd)0或read(connfd)0时,需要两个进程都退出,此处用SIGUSR1作为通知信号

    client.c

    #include <unistd.h>
    #include <signal.h>
    #include <errno.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <sys/socket.h>
    #include <arpa/inet.h>
    #include <netinet/in.h>
     
    void err_quit(const char *s){
        perror(s);
        exit(1);
    }
     
    void handler(int signo){
        printf("program terminated
    ");
        exit(0);
    }
     
    int main(int argc,char *argv[]){
        int sockfd;
        struct sockaddr_in servaddr;
        char buff[1024];
        pid_t child;
     
        if((sockfd=socket(PF_INET,SOCK_STREAM,0)) < 0)
            err_quit("socket");
     
        bzero(&servaddr,sizeof(servaddr));
        servaddr.sin_family=AF_INET;
        servaddr.sin_addr.s_addr=inet_addr("127.0.0.1");
        servaddr.sin_port=htons(5566);
     
        if(connect(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr)) <0)
            err_quit("connect");
     
        if((child=fork()) <0)
            err_quit("fork");
        else if(child == 0){
            signal(SIGUSR1,handler);
            while(fgets(buff,sizeof(buff),stdin) != NULL)
                write(sockfd,buff,strlen(buff));
        }else{
            while(1){
                memset(buff,0,sizeof(buff));
                int nread=read(sockfd,buff,sizeof(buff));
                if(nread == -1)
                    err_quit("read");
                if(nread == 0){
                   printf("perr closed
    ");
                   break;
                }
                fputs(buff,stdout);
            }
            kill(child,SIGUSR1);
        }
        exit(0);
    }
    

    server.c

    #include <unistd.h>
    #include <errno.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <signal.h>
    #include <sys/wait.h>
    #include <sys/socket.h>
    #include <arpa/inet.h>
    #include <netinet/in.h>
     
    void err_quit(const char *s){
        perror(s);
        exit(1);
    }
     
    void handler(int signo){
        printf("program terminated
    ");
        exit(0);
    }
     
    int main(int argc,char *argv[]){
        int sockfd,connfd;
        pid_t child;
        socklen_t len;
        struct sockaddr_in addr,client;
        char buff[1024];
     
        if((sockfd=socket(PF_INET,SOCK_STREAM,0)) < 0)
            err_quit("sockfd");
     
        bzero(&addr,sizeof(addr));
        addr.sin_family=AF_INET;
        addr.sin_addr.s_addr=htonl(INADDR_ANY);
        addr.sin_port=htons(5566);
     
        int on=1;
        if(setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on)) <0)
            err_quit("setsockopt");
     
        if(bind(sockfd,(struct sockaddr *)&addr,sizeof(addr))<0)
            err_quit("bind");
     
        if(listen(sockfd,10)<0)
            err_quit("listen");
     
        len=sizeof(client);
        connfd=accept(sockfd,(struct sockaddr *)&client,&len);
        if(connfd < 0)
            err_quit("accept");
     
        if((child=fork())<0){
            err_quit("fork");
        }else if(child  == 0){
            while(1){
                bzero(buff,sizeof(buff));
                int nread=read(connfd,buff,1024);
                if(nread == -1)
                    err_quit("read");
                if(nread == 0){
                    printf("peer closed
    ");
                    break;
                }
                fputs(buff,stdout);
            }
            kill(getppid(),SIGUSR1);
        }else{
            signal(SIGUSR1,handler);
            while(fgets(buff,sizeof(buff),stdin) != NULL){
                write(connfd,buff,strlen(buff));
            }
        }
        exit(0);
    }
    
  • 相关阅读:
    自定义注解(注解扫描)
    Redis缓存淘汰策略
    粘包问题
    MySQL事务日志
    分布式事务
    https的工作流程
    CAP原则和BASE理论
    设计模式(一)
    限流的原理以及常用算法
    散列冲突(哈希碰撞)的解决办法
  • 原文地址:https://www.cnblogs.com/cfans1993/p/6131904.html
Copyright © 2020-2023  润新知