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;
    }

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

    技术不分国界
  • 相关阅读:
    安全编码1
    VPP tips
    VPP概述汇总
    C语言安全编码摘录
    TCP-proxy
    Scipy Lecture Notes学习笔记(一)Getting started with Python for science 1.4. Matplotlib: plotting
    Scipy Lecture Notes学习笔记(一)Getting started with Python for science 1.3. NumPy: creating and manipulating numerical data
    Scipy Lecture Notes学习笔记(一)Getting started with Python for science 1.2. The Python language
    Scipy Lecture Notes学习笔记(一)Getting started with Python for science 1.1. Python scientific computing ecosystem
    25马5跑道,求最快的五匹马的需要比赛的次数
  • 原文地址:https://www.cnblogs.com/angels-yaoyao/p/12443608.html
Copyright © 2011-2022 走看看