zoukankan      html  css  js  c++  java
  • Linux一对多的通信

    客户端:

    #include <unistd.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <arpa/inet.h>
    #include <pthread.h>
    #include <sys/socket.h>
    #include <sys/types.h>
    #include <sys/signal.h>
    
    #define MAXLEN 1024
    
    typedef struct mysocketinfo{
        int socketcon;
        unsigned long ipaddr;
        unsigned short port;
    }_mysocketinfo;
    
    void *fun_thrreceivehandler(void *socketcon);
    
    const char *ip="127.0.0.1";
    const int port=8888;
    
    int main()
    {
        ssize_t size=0; 
    
        //signal(SIGQUIT,SIG_IGN);
        printf("start socket
    ");
        int socketcon=socket(AF_INET,SOCK_STREAM,0);
        if(socketcon<0)
        {
            perror("socket error
    ");
            exit(1);
        }
    
        struct sockaddr_in server_addr;
        server_addr.sin_family=AF_INET;
        server_addr.sin_addr.s_addr=inet_addr(ip);
        server_addr.sin_port=htons(port);
    
        printf("socketcon:%d
    ",socketcon);
    
        int res_con=connect(socketcon,(struct sockaddr*)(&server_addr),sizeof(struct sockaddr));
        if(res_con!=0)
        {
            perror("connect error
    ");
            exit(2);
        }
    
        printf("连接成功
    ");
        pthread_t thrreceive;
        pthread_create(&thrreceive,NULL,fun_thrreceivehandler,&socketcon);
    
        while(1){
            char buf[MAXLEN];
            memset(buf,'',sizeof(buf));
    
            size=read(STDIN_FILENO,buf,sizeof(buf)-1);
            if(size>0)
            {
                buf[size]='';
            }
            else if(size==0)
            {
                printf("不能为空
    ");
                break;
            }
            else{
                perror("read error
    ");
                break;
            }
    
            int sendmsg_len=write(socketcon,buf,size);
            if(sendmsg_len>0)
            {
                printf("发送成功,客户端套接字:%d
    ",socketcon);
            }
            else{
                printf("发送失败!
    ");
            }
            sleep(2);
    
        }
        close(socketcon);
        exit(0);
    }
    
    void *fun_thrreceivehandler(void *socketcon)
    {
        while(1)
        {
            char buffer[MAXLEN];
            int _socketcon=*((int*)socketcon);
            int buffer_length=read(_socketcon,buffer,MAXLEN);
            buffer[buffer_length+1]='';
            if(buffer_length<=0)
            {
                printf("空数据
    ");
                exit(0);
            }
            printf("服务器:%s
    ",buffer);
        }
        exit(0);
    }
    
    
    
    
    
    
    
    
    
    
    
    

    服务端:

    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/socket.h>
    #include <arpa/inet.h>
    #include <string.h>
    #include <pthread.h>
    #include <signal.h>
    
    #define MAXLEN 1024
    #define MAXTHR 10
    
    const int port=8888;
    const char *service_ip="127.0.0.1";
    
    //记录线程的变量
    int pthreadnum=0;
    
    //连接到的客户端的数量
    int conclientcount=0;
    
    typedef struct mysocketinfo{
        int socketcon;
        char *ipaddr;
        uint16_t port;
    }_mysocketinfo;
    //
    struct mysocketinfo arrconsocket[10];
    
    //接受客户端线程列表
    //接收到的客户端线程
    pthread_t arrthrreceiveclient[10];
    //接受到的客户端的数量
    int thrreceiveclientcount=0;
    
    //删除杀死的线程
    int delete_client(void *fp,int num)
    {
        int i=0;
    
        pthread_t *ps=(pthread_t *)fp;
    
        if(num<1)
        {
            return 0;   
        }
    
        for(i=num;i<thrreceiveclientcount;i++)
        {
            ps[i]=ps[i+1];  
        }
        return 1;
    }
    
    
    int checkthriskill(pthread_t thr)
    {
        //1存在,0不存在
        int res=1;
        //判断线程是否存在
        int res_kill=pthread_kill(thr,0);
        if(res_kill==0)
        {
            res=0;
        }
        return res;
    }
    
    void *fun_thrreceivehandler(void *socketcon){
        char buffer[MAXLEN];
        int buffer_length;
        int _socketcon;
    
        while(1){
            memset(buffer,'',sizeof(buffer));
            _socketcon=*((int*)socketcon);
    
            printf("接收套接字:%d
    ",_socketcon);
    
            buffer_length=read(_socketcon,buffer,MAXLEN);
            if(buffer_length==0){
                printf("不能为空
    ");
                break;
            }
            else if(buffer_length<0){
                printf("接受客户端数据失败了
    ");
                break;
            }
            buffer[buffer_length]='';
            printf("%d:%s
    ",_socketcon,buffer);
    
            sleep(1);
        }
        printf("接受数据线程结束
    ");
    }
    
    void *fun_thraccepthander(void *socketlisten){
        char buf[MAXLEN];
        ssize_t size;
    
        while(1){
        int sockaddr_in_size=sizeof(struct sockaddr_in);
        struct sockaddr_in client_addr;
        int socklisten1=*((int *)socketlisten);
        int socketcon=accept(socklisten1,(struct sockaddr*)(&client_addr),(socklen_t *)(&sockaddr_in_size));
        if(socketcon<0){
            perror("accept error
    ");
            exit(5);
        }
        else{
            printf("accept success
    ");
            printf("ip:%s,port:%d
    ",inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port));
        }
    
        ++conclientcount;
    
        printf("在线人数:%d
    ",conclientcount);
        printf("连接套接字:%d
    ",socketcon);
    
        _mysocketinfo socketinfo;
        socketinfo.socketcon=socketcon;
        socketinfo.ipaddr=inet_ntoa(client_addr.sin_addr);
        socketinfo.port=client_addr.sin_port;
        arrconsocket[conclientcount]=socketinfo;//成功,从1开始的
    
        //接受消息
        pthread_t thrreceive=0;
        pthread_create(&thrreceive,NULL,fun_thrreceivehandler,&socketcon);
        arrthrreceiveclient[thrreceiveclientcount]=thrreceive;
        thrreceiveclientcount++;
        sleep(1);
        }
    }
    
    int main()
    {   
        ssize_t size=0;
        sigset_t newmask,oldmask,pendmask;
    
        sigemptyset(&newmask);
        sigaddset(&newmask,SIGQUIT);
        if(sigprocmask(SIG_BLOCK,&newmask,&oldmask)<0)
            perror("sigprocmask error
    ");
        sleep(2);
    
        int service_socket=socket(AF_INET,SOCK_STREAM,0);
        if(service_socket<0)
        {
            perror("service create error
    ");
            exit(1);
        }
    
        struct sockaddr_in addr;
        addr.sin_family=AF_INET;
        addr.sin_port=htons(port);
        addr.sin_addr.s_addr=inet_addr(service_ip);
    
        if(bind(service_socket,(struct sockaddr*)&addr,sizeof(addr))<0)
        {
            perror("bind error
    ");
            exit(2);
        } 
    
        int listen_socket=listen(service_socket,10);
        if(listen_socket<0)
        {
            perror("listen error
    ");
            exit(3);
        }
    
        pthread_t thraccept[MAXTHR];
        if(pthread_create(&thraccept[++pthreadnum],NULL,fun_thraccepthander,&service_socket)!=0)
        {
            perror("pthread_create error
    ");
            exit(4);
        }
        sleep(1);   
    
        while(1){
            int i=0;
            int n=0;
            int m=0;
            for(i=0;i<thrreceiveclientcount;i++){
                if(checkthriskill(arrthrreceiveclient[i])==1)
                {
                    printf("有个线程被杀了
    ");
                    if(delete_client((void *)(&arrthrreceiveclient),i)==0)
                        printf("delete error
    ");
                    thrreceiveclientcount--;
                    for(n=thrreceiveclientcount+2;n<=conclientcount;n++)
                    {
                        arrconsocket[n]=arrconsocket[n+1];
                    }
                    conclientcount--;
                    for(m=thrreceiveclientcount+2;m<=pthreadnum;m++)
                    {
                        thraccept[m]=thraccept[m+1];
                    }
                    pthreadnum--;
                }
            }
            printf("当前接受数据线程:%d
    ",thrreceiveclientcount);
            if(conclientcount<=0)
            {
                printf("客户端没有连接
    ");
            }
            else{
                int i=0;
                char buf[MAXLEN];
    
                memset(buf,'',sizeof(buf));
                size=read(STDIN_FILENO,buf,sizeof(buf)-1);
                if(size>0)
                {
                    buf[size+1]='';
                }
                else if(size==0)
                {
                    printf("不能为空
    ");
                    size=read(STDIN_FILENO,buf,sizeof(buf)-1);
                }
                else{
                    perror("read error
    ");
                    break;
                }
    
                for(i=0;i<=conclientcount;i++){
    
                    int sendmsg_len=write(arrconsocket[i].socketcon,buf,size);
                    if(sendmsg_len>0)
                    {
                        printf("向%s:%d发送成功
    ",arrconsocket[i].ipaddr,arrconsocket[i].port);
    
                    }
                    else
                    {
                        printf("向%s:%d发送失败
    ",arrconsocket[i].ipaddr,arrconsocket[i].port);
                    }
                }
            }
            sleep(1);
        }
        printf("等待子进程退出,即将退出!
    ");
        char *message;
        int j=0;
        for(j=0;j<pthreadnum;j++)
        {
            pthread_join(thraccept[j],(void*)&message);
    
            printf("%s
    ",message);
        }
        if(sigprocmask(SIG_SETMASK,&oldmask,NULL)<0)
            perror("sigprocmask error
    ");
        printf("SIGQUIT unblocked");
        return 0;
    }

    实现了简单的一对多的通信,但是其中一个客户端终止时,会出现,数据的不一致性,可以通过构造一个数据结构来解决问题

    技术不分国界
  • 相关阅读:
    lamp
    ssh 交互脚本
    mysql 备份检测主从脚本
    RANDOM 猜数字脚本
    ansible+playbook 搭建lnmp环境
    集群搭建
    grafana
    nginx lnmp搭建
    shell 基础(1): 变量
    seq 增量输出命令
  • 原文地址:https://www.cnblogs.com/angels-yaoyao/p/12443608.html
Copyright © 2011-2022 走看看