zoukankan      html  css  js  c++  java
  • (完善之后的程序)linuxTCP一对多通信

    服务端:

    #include <unistd.h>
    #include <stdio.h>
    #include <sys/socket.h>
    #include <stdlib.h>
    #include <signal.h>
    #include <pthread.h>
    #include <string.h>
    #include <arpa/inet.h>
    #include <errno.h>
    
    #define MAXLEN 1024
    #define MAXTHR 10
    
    const int port=8888;
    const char *ip="127.0.0.1";
    
    typedef struct mysocketinfo{
        int socketcon;
        char *ipaddr;
        uint16_t port;
    }_mysocketinfo;
    
    pthread_t arrthrreceiveclient[10];
    struct mysocketinfo arrconsocket[10];
    int arr=0;
    
    int checkthriskill(pthread_t thr)
    {
           //1存在,0不存在
            int res=1;
            //判断线程是否存在
            int kill_rc=pthread_kill(thr,0);
    
            if(kill_rc==3)
                printf("指定的线程不存在或已退出
    ");
            else if(kill_rc==2)
                printf("信号无效
    ");
            else
                printf("指定线程是活着的
    ");
    
            if(kill_rc==0)
            {
            res=0;
            }
            return res;
    }
    
    //接收消息函数
    void *fun_thrreceivehandler(void *socketcon){
        char buffer[MAXLEN];
        int buffer_length;
        int socketcon1;
    
    
        socketcon1=*((int*)socketcon);
        while(1){
            memset(buffer,'',sizeof(buffer));//或者使用函数bzero(buffer,20);
    
            printf("接收套接字:%d
    ",socketcon1);
            buffer_length=read(socketcon1,buffer,MAXLEN-1);
            if(buffer_length<0)
            {
                printf("接收客户端失败了
    ");
            }
            else if(buffer==NULL)
            {
                pthread_exit("线程退出");   
            }
            if(strcmp(buffer,"quit")==0)
            {
                int i=0;
                int k=0;
    
                fprintf(stdout,"套接字:%d close",socketcon1);
                for(i=0;i<=arr;i++)
                {
                    if(arrconsocket[i]==socketcon1)
                    {
                        for(k=i;k<=arr;k++)
                        {
                            arrconsocket[k]=arrconsocket[k+1];
                            arrthrreceiveclient[k]=arrthrreceiveclient[k+1];
                        }
                    }
                }
    
            }
            printf("buffer:%s
    ",buffer);
            buffer[buffer_length]='';
            printf("客户端%d:%s
    ",socketcon1,buffer);
            sleep(1);
        }
         printf("接受数据线程结束
    ");
    }
    
    //删除杀死的线程
    int delete_client(void *fp,int num)
    {
        /*
        int pthreadnum=0;
        int thrreceiveclientcount=0;//接收消息的线程ID
        int conclientcount=0;//在线人数
        */
    
        int i=0;
    
        pthread_t *ps=(pthread_t *)fp;
    
        if(num<1)
        {
            return 0;   
        }
    
        for(i=num;i<=arr;i++)
        {
            ps[i]=ps[i+1];  
        arrconsocket[i]=arrconsocket[i+1];
        }
    
        return 1;
    }
    
    //处理acceot
    void *fun_thraccepthander(void *socketlisten){
        char buf[MAXLEN];
        ssize_t size;
        int sockaddr_in_size=sizeof(struct sockaddr_in);//sockaddr_in结构体的大小
        struct sockaddr_in client_addr;
        int socklisten1=*((int*)socketlisten);
        int socketcon;
    
        while(1){
        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));
        }
    
    
        printf("在线人数:%d
    ",++arr);
            printf("连接套接字:%d
    ",socketcon);
    
        arrconsocket[arr].socketcon=socketcon;
        arrconsocket[arr].ipaddr=inet_ntoa(client_addr.sin_addr);
        arrconsocket[arr].port=client_addr.sin_port;
    
        //接收的消息
        pthread_t thrreceive=0;
        if(pthread_create(&thrreceive,NULL,fun_thrreceivehandler,&socketcon)!=0)
        {
            perror("pthread_create error
    ");
            exit(6);
        }
        arrthrreceiveclient[arr]=thrreceive;
        sleep(1);
        }
    
    }
    
    void *fun_thrfile(void *socketcon)
    {
        int _socketcon=*((int *)socketcon);
        int sockfd,addrlen,n;
        struct sockaddr_in addr;
        char buf[MAXLEN];
        int sock_tmp;
        int count=0;
        int k=0;
        int m=0;
    
        sockfd=socket(AF_INET,SOCK_DGRAM,0);//服务端的数据报
        if(sockfd<0)
        {
            fprintf(stderr, "socket failed
    ");  
                exit(EXIT_FAILURE);
        }   
    
        addrlen=sizeof(struct sockaddr_in);
        bzero(&addr,addrlen);
        addr.sin_family=AF_INET;
        addr.sin_addr.s_addr=htonl(INADDR_ANY);
        addr.sin_port=htons(9999);
    
        if(bind(sockfd,(struct sockaddr*)(&addr),sizeof(addr))<0)
        {
            fprintf(stderr, "socket failed
    ");  
                exit(EXIT_FAILURE);
        }
        puts("bind success");
    
        bzero(buf,MAXLEN);
        while(1)
        {
            n=recvfrom(sockfd,buf,sizeof(buf),0,(struct sockaddr *)(&addr),&addrlen);
            if(n>0)
            {
                sock_tmp=atoi(buf);
                fprintf(stdout,"sock_tmp:%d",sock_tmp);
            }
            else
            {
                count++;
            }
            if(count==3)
            {
                for(k=0;k<=arr;k++)
                {
                    if(arrconsocket[k].socketcon==sock_tmp)
                    {
                        for(m=k;m<=arr;m++)
                        {
                            arrconsocket[k]=arrconsocket[k+1];
                            arrthrreceiveclient[k]=arrthrreceiveclient[k+1];
                        }
                        arr-=1;
                        break;
                    }
                }
            }           
            sleep(3);
        }
    }
    
    
    int main()
    {
        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(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;//创建的线程数组
        //pthread_create创建线程(实际上就是确定调用该线程函数的入口点),在线程创建以后,就开始运行相关的线程函数
        if(pthread_create(&thraccept,NULL,fun_thraccepthander,&service_socket)!=0)
        {
            perror("pthread_create error
    ");
            exit(4);
        }
        sleep(1);
        pthread_t thrfile;
        if(pthread_create(&thrfile,NULL,fun_thrfile,&service_socket)!=0)
        {
            perror("pthread_create error
    ");
            exit(4);
        }
        sleep(1);
    
        while(1)
        {
            int i=1;
            for(i=1;i<=arr;i++)
            {
                if(checkthriskill(arrthrreceiveclient[i])==1)
                {
                    printf("have a thread is killed
    ");
                    if(delete_client((void*)(&arrthrreceiveclient),i)==0)
                    {
                        printf("delete_client error
    ");
                        exit(6);
                    }
                    --arr;
                }
            }
            printf("当前接收进程数据线程:%d
    ",arr);
            if(arr<=0)
            {
                printf("没有客户端连接
    ");
            }
            else
            {
                int i=0;
                char buf[MAXLEN];
                ssize_t size=0;
    
                memset(buf,'',MAXLEN);
                size=read(STDIN_FILENO,buf,sizeof(buf));
                if(size>0)
                {
                    buf[size]='';
                }
                else
                {
                    perror("read error
    ");
                    break;
                }
    
                for(i=1;i<=arr;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);
                    }
                }
            }
            //pthread_join(id1,&a1);
            sleep(1);
        }
        if(arr>=1)
        {
            char *message;
            int j=1;
            int res=1;
            printf("等待线程退出
    ");
    
    
    
                if((res=pthread_join(thraccept,(void*)&message))==0)
                {
                    printf("%s
    ",message);
                }
                else
                {
                    printf("pthread_join error:%d
    ",res);
                }
    
        }
        else
        {
            printf("没有线程
    ");
        }
        close(service_socket);
        pthread_kill(thraccept,SIGKILL);
        return(0);
    }

    客户端:

    #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);
    void *fun_thrfile(void *socketcon);
    
    const char *ip="127.0.0.1";
    const int port=8888;
    pthread_t thrreceive;
    pthread_t thrfile;
    int socketcon;
    int sockfd;
    
    int main()
    {
    
        sigset_t newmask,pendmask;
    
        sigemptyset(&newmask);
        sigaddset(&newmask,SIGQUIT);
        sigaddset(&newmask,SIGINT);
        if(sigprocmask(SIG_BLOCK,&newmask,NULL)<0)
            printf("SIG_BLOCK error
    ");    
    
        printf("start socket
    ");
        socketcon=socket(AF_INET,SOCK_STREAM,0);
        if(socketcon<0)S
        {
            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("连接成功
    ");
        if(pthread_create(&thrreceive,NULL,fun_thrreceivehandler,&socketcon)!=0)
        {
        perror("pthread_create error
    ");
            exit(3);
        }
        sleep(2);
        if(pthread_create(&thrfile,NULL,fun_thrfile,&socketcon)!=0)
        {
            perror("pthread_create error
    ");
            exit(4);
        }
        sleep(1);
    
        while(1){
            char buf[MAXLEN];
        int size=0;
            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("发送失败!
    ");
            }
    
        if(strcmp(buf,"quit")==0)
        {
            close(socketcon);
                pthread_kill(thrreceive,SIGKILL);
            close(sockfd);
            pthread_kill(thrfile,SIGKILL);
        }
    
            sleep(2);
    
        }
    
        close(socketcon);
        pthread_kill(thrreceive,SIGKILL);
        if(sigpending(&pendmask)<0)
            printf("sigpending error
    ");
        if(sigismember(&pendmask,SIGQUIT))
            printf("
    SIGQUIT Pending
    ");
        if(sigismember(&pendmask,SIGINT))
            printf("
    SIGINT Pending
    ");
        exit(0);
    }
    
    void *fun_thrreceivehandler(void *socketcon)
    {
        char buffer[MAXLEN];
        int _socketcon=*((int*)socketcon);
        while(1)
        {
        memset(buffer,'',sizeof(buffer));
            int buffer_length=read(_socketcon,buffer,MAXLEN-1);
            buffer[buffer_length]='';
            if(buffer_length<=0)
            {
                printf("空数据
    ");
                exit(0);
            }
            printf("服务器:%s
    ",buffer);
        }
        pthread_kill(thrreceive,SIGKILL);
        exit(0);
    }
    
    void *fun_thrfile(void *socketcon)
    {
        int _socketcon=*((int *)socketcon);
        int addrlen,n;
        struct sockaddr_in addr;
        int buflength=0;
        char buf[MAXLEN];
    
        sockfd=socket(AF_INET,SOCK_DGRAM,0);//数据报
        if(sockfd<0)
        {
            fprintf(stderr,"socker failed
    ");
            exit(EXIT_FAILURE);
        }
    
        addrlen=sizeof(struct sockaddr_in);
        bzero(&addr,addrlen);//清空addr   
        addr.sin_family=AF_INET;
        addr.sin_addr.s_addr=htonl(INADDR_ANY);
        addr.sin_port=htons(9999);
    
    
        bzero(buf,MAXLEN);
        buflength=sprintf(buf,"%d",_socketcon);
        buf[buflength]='';
        fprintf(stdout,"_socketcon:%d",buf);
    
        while(1)
        {
            n=sendto(sockfd,buf,buflength,0,(struct sockaddr*)(&addr),addrlen);
            if(n<=0)
            {
                fprintf(stderr,"sendto error
    ");
                exit(EXIT_FAILURE);
            }
            sleep(1);
        }
        close(sockfd);
        pthread_kill(thrfile,SIGKILL);
        exit(0);
    }

    完善了以前编写程序出现的一些BUG。

    技术不分国界
  • 相关阅读:
    Fastjson
    react 使用createContext、Consumer 及 useContext 、Class.contextType父子组件共享数据
    使用useReducer 实现 todoList
    react中 useMemo与useCallback使用
    react17 函数组件 使用 better-scroll2.0 封装方法 及 使用
    react 执行 yarn build ,无法直接打开dist文件下的index
    react-redux 持久数据存储
    document.body.removeChild 获取到 symbol 标签
    react嵌套路由,并设置默认子路由
    Vagrant环境下配置node_exporter、mysqld_exporter、prometheus、grafana
  • 原文地址:https://www.cnblogs.com/angels-yaoyao/p/12443605.html
Copyright © 2011-2022 走看看