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\n");

        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\n");

        return -1;

    }



    // server socket start list, waitting client to connect

    // 这个client_max是指同时连接数

    if(listen(sockfd_server, client_max) == -1)

    {

        printf("start listen socket failed\n");

        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...\n");

        

        // waitting for connected

        sockfd_client = accept(sockfd_server, (struct sockaddr*)&addr_client, &addr_len);

        if(sockfd_client == -1)

        {

            printf("accept socket failed\n");

            return -1;

        }

        

        // create a thread to talk with client

        printf("recived connection from : %s\n", 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\n", szBuf);

        

        if(strcmp(szBuf, "quit") == 0)

        {

            break;

        }

        

        sprintf(szBuf, "Your magic number is : %d", rand()%100);

        printf("server : %s\n", 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\n", 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\n");

        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\n");

        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] = '\0';

            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\n", szBuf);

        

        if(strcmp(szBuf, "quit") == 0)

        {

            break;

        }

    }

    return NULL;

}

 

你可能感兴趣的:(linux)