zoukankan      html  css  js  c++  java
  • Linux下使用多线程模拟异步网络通信

    服务器

    /* socket server
     * 2014-12-15 CopyRight (c) arbboter
     */
    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <sys/socket.h>
    #include <sys/types.h>
    #include <netdb.h>
    #include <string.h>
    #include <arpa/inet.h>
    #include <pthread.h>
    #include <vector>
    using namespace std;
    
    vector<int> vecClient;
    // 线程同步锁
    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;  
    
    void* recv_thr(void*p);
    void* send_thr(void*p);
    int main()
    {
        int sockfd_server;
        int sockfd_client;
        struct sockaddr_in addr_server;
        struct sockaddr_in addr_client;
        socklen_t addr_len = 0;
        int client_max = 10;
        int server_port = 33891;
    
        srand(time(NULL));
        
        // create socket
        sockfd_server = socket(AF_INET, SOCK_STREAM, 0);
        if(sockfd_server == -1)
        {
            printf("init socket failed
    ");
            return -1;
        }
    
        // set address
        memset(&addr_server, 0, sizeof(addr_server));
        addr_server.sin_family = AF_INET;
        addr_server.sin_addr.s_addr = htonl(INADDR_ANY);
        addr_server.sin_port = htons(server_port);
        
        // socket bind with address
        if(bind(sockfd_server, (struct sockaddr*)&addr_server, sizeof(struct sockaddr)) == -1)
        {
            printf("bind socket failed
    ");
            return -1;
        }
    
        // server socket start list, waitting client to connect
        // 这个client_max是指同时连接数
        if(listen(sockfd_server, client_max) == -1)
        {
            printf("start listen socket failed
    ");
            return -1;
        }
    
        // 数据线程
        pthread_t tid = 0;
        
        pthread_create(&tid, NULL, send_thr, NULL);
        while(1)
        {
            addr_len = sizeof(struct sockaddr_in);
            printf("waitting for connected...
    ");
            
            // waitting for connected
            sockfd_client = accept(sockfd_server, (struct sockaddr*)&addr_client, &addr_len);
            if(sockfd_client == -1)
            {
                printf("accept socket failed
    ");
                return -1;
            }
            
            // create a thread to talk with client
            printf("recived connection from : %s
    ", inet_ntoa(addr_client.sin_addr));
            pthread_create(&tid, NULL, recv_thr, (void*)&sockfd_client);
            
            // 加到发数据对象集合中
            pthread_mutex_lock(&mutex);  
            vecClient.push_back(sockfd_client);
            pthread_mutex_unlock(&mutex); 
        }
        close(sockfd_server);
        pthread_mutex_destroy(&mutex);
        return 0;
    }
    
    // 收数据
    void* recv_thr(void*p)
    {
        int fd = *((int*)p);
        int nRead = 0;
        char szBuf[512] = {0};
        
        while(1)
        {
            memset(szBuf, 0, sizeof(szBuf));
            nRead = read(fd, szBuf, sizeof(szBuf));
            printf("client : %s
    ", szBuf);
            
            if(strcmp(szBuf, "quit") == 0)
            {
                break;
            }
            
            sprintf(szBuf, "Your magic number is : %d", rand()%100);
            printf("server : %s
    ", szBuf);
            write(fd, szBuf, strlen(szBuf));
        }
        return NULL;
    }
    
    // 发数据
    void* send_thr(void*p)
    {
        size_t i = 0;
        char szBuf[512] = {0};
        
        while(1)
        {
            sleep(rand()%10);
            pthread_mutex_lock(&mutex);  
            for(int i=0; i<vecClient.size(); i++)
            {
                sprintf(szBuf, "Your magic number is : %d", rand()%100);
                printf("[%02d] server : %s
    ", i, szBuf);
                write(vecClient[i], szBuf, strlen(szBuf));
            }
            pthread_mutex_unlock(&mutex); 
        }
        return NULL;
    }

    客户端

    /* socket client
     * 2014-12-15 CopyRight (c) arbboter
     */
    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/socket.h>
    #include <sys/types.h>
    #include <netdb.h>
    #include <string.h>
    #include <arpa/inet.h>
    #include <pthread.h>
    #include <signal.h>
    #include <errno.h>
    #include <string.h>
    
    void* recv_thr(void*p);
    int main()
    {
        int sockfd_server;
        struct sockaddr_in addr_server;
        socklen_t addr_len = 0;
        int server_port = 33891;
        char* server_addr = "192.168.2.200";
    
    
        // create socket
        sockfd_server = socket(AF_INET, SOCK_STREAM, 0);
        if(sockfd_server == -1)
        {
            printf("init socket failed
    ");
            return -1;
        }
        
        // set server address
        memset(&addr_server, 0, sizeof(addr_server));
        addr_server.sin_family = AF_INET;
        addr_server.sin_addr.s_addr = inet_addr(server_addr);;
        addr_server.sin_port = htons(server_port);
        
        // connect server
        if(connect(sockfd_server,(struct sockaddr *)&addr_server,sizeof(struct sockaddr))==-1)
        {
            printf("connect server failed
    ");
            return -1;
        }
        
        // 启动收数据线程
        pthread_t tid = 0;
        pthread_create(&tid, NULL, recv_thr, (void*)&sockfd_server);
        
        // 发送数据
        char szBuf[512] = {0};
        int nLen = 0;
        while(1)
        {
            // 收线程已退出
            if( ESRCH == pthread_kill(tid,0) )
            {
                break;
            }
            // 等待输入数据
            gets(szBuf);
            nLen = strlen(szBuf);
            if(nLen > 0)
            {
                szBuf[nLen] = '';
                write(sockfd_server, szBuf, nLen);
            }
        }
        close(sockfd_server);
        return 0;
    }
    
    // 收数据
    void* recv_thr(void*p)
    {
        int fd = *((int*)p);
        int nRead = 0;
        char szBuf[512] = {0};
        
        while(1)
        {
            memset(szBuf, 0, sizeof(szBuf));
            nRead = read(fd, szBuf, sizeof(szBuf));
            printf("server : %s
    ", szBuf);
            
            if(strcmp(szBuf, "quit") == 0)
            {
                break;
            }
        }
        return NULL;
    }
  • 相关阅读:
    CTFHub-Web-Web前置技能-HTTP协议-响应包源代码详解
    BurpSuite环境安装及设置
    i2 Analyst’s Notebook 9学习笔记之入门、基本概念和数据接口
    Python 练习题:用索引取出LIST中的值
    python 练习题:小明的成绩从去年的72分提升到了今年的85分,请计算小明成绩提升的百分点
    zabbix4.0 本地安装详解及步骤
    CentOS 7 安装 mysql 5.7.27 for zabbix
    win7系统 右击任务栏 资源管理器 弹出菜单“已固定”和“最近”项目不显示故障处理
    CentOS 7 新系统 手动配置网络 简要步骤
    CentOS7 firewalld防火墙 启动 关闭 禁用 添加删除规则等 常用命令
  • 原文地址:https://www.cnblogs.com/arbboter/p/4167672.html
Copyright © 2011-2022 走看看