socket接口多线程数据传输

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了socket接口多线程数据传输相关的知识,希望对你有一定的参考价值。

socket接口多线程数据传输

服务端代码

myserver.c

#include <sys/socket.h>
#include <sys/types.h>
#include <signal.h>
#include <string.h>
#include <netinet/in.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <arpa/inet.h>

#define PORT_NUM     5555
#define    MAX_CLIENT    100

typedef struct {
            int    index;
            int    using;        //using or not
            pthread_t tid;
            int client_com_fd;
            struct sockaddr_in client_addr;
            int     client_addr_len;
}mythread_arg_t;

mythread_arg_t    pthread_arg_array[MAX_CLIENT];

print_thread(int index)
{
    int    i = index;

    printf("=======================thread data=======================\n");
    printf("pthread_arg_array[i].index = %d\n", pthread_arg_array[i].index);
    printf("pthread_arg_array[i].using = %d\n", pthread_arg_array[i].using);
    printf("pthread_arg_array[i].tid = 0x%lx\n", pthread_arg_array[i].tid);
    printf("pthread_arg_array[i].client_com_fd = %d\n", pthread_arg_array[i].client_com_fd);
    printf("pthread_arg_array[i].client_addr = %s\n", inet_ntoa(pthread_arg_array[i].client_addr.sin_addr));
    printf("=======================thread end========================\n");
}

void *do_client( void *arg)
{
    char buf[1400];

    int i = (int)(long)arg;
    while(1) 
    {
        int ret = recv(pthread_arg_array[i].client_com_fd, buf, sizeof(buf), 0);
        if(ret == -1 || ret == 0) 
        {
            perror("recv");
            break;
        }

        if(!strncmp(buf, "exit", 4))
        {
            break;
        }

        printf("recv from client address: %s data: %s\n", inet_ntoa(pthread_arg_array[i].client_addr.sin_addr), buf);

    }
    print_thread(i);

    close(pthread_arg_array[i].client_com_fd);
    pthread_arg_array[i].using = 0;
}

void client_exit(int signo)
{
    pid_t pid;

    pid = wait( NULL );            
    //close( listen_fd );
    printf("pid = %d exit.\n", pid );
}

int main( int argc, char ** argv )
{
    int listen_fd = socket( AF_INET, SOCK_STREAM, 0 );    
    
    struct sockaddr_in myaddr;
    myaddr.sin_family = AF_INET;
    myaddr.sin_port = htons(PORT_NUM);
    myaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    int ret;
    int    i;

    signal(SIGCHLD, client_exit);

    ret = bind(listen_fd, (struct sockaddr *)&myaddr, sizeof(struct sockaddr));
    if(-1 == ret) 
    {
        perror("bind");
        exit(1);
    }

    listen(listen_fd, 20);

    struct sockaddr_in client_addr;
    int client_addr_len = sizeof(struct sockaddr);
    int client_com_fd;

    while(1) 
    {
        //find an no using entry
        for(i = 0; (i < MAX_CLIENT)&&(1 == pthread_arg_array[i].using); i++)
            ;
        if(i >= MAX_CLIENT)
        {
            printf("overload!\n");
            close(client_com_fd);
            continue;
        }

        printf("i = %d\n", i );

        client_com_fd = accept(listen_fd,(struct sockaddr *)&client_addr, &client_addr_len);
        pthread_arg_array[i].using = 1;
        printf("ip address %s have send connect request.\n", inet_ntoa(client_addr.sin_addr));

        pthread_arg_array[i].index = i;
        pthread_arg_array[i].client_com_fd = client_com_fd;
        pthread_arg_array[i].client_addr = client_addr;
        pthread_arg_array[i].client_addr_len = client_addr_len;

        pthread_t *ptid = &(pthread_arg_array[i].tid);

        if(-1 == pthread_create(ptid, NULL, do_client, (void *)(long)i))
        {
            printf("pthread_creat()\n");
            continue;
        }

/*
        pid_t pid;
        pid = fork();
        if( pid < 0 ) {
            perror("fork");
            exit( 3 );
        } else if( pid == 0 ) {
            close( listen_fd );            
            do_client( client_com_fd, client_addr );
            close( client_com_fd );
            exit( 0 );
        }
*/
    }
    
    //close( client_com_fd );
    //close( listen_fd );
}

客户端代码

myclient.c

#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <stdio.h>

#define PORT_NUM     5555
#define LENGTH  1460

int main(int argc, char *argv[])
{
    if(2 != argc) {
        exit(1);
    }

    int sock_fd = socket(AF_INET, SOCK_STREAM, 0);

    struct sockaddr_in server_addr;
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(PORT_NUM);
    server_addr.sin_addr.s_addr = inet_addr(argv[1]);

    int ret = connect(sock_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr));
    if(-1 == ret) {
        perror("connect");
        exit(2);
    }

    char buf[LENGTH];

    while(1) {
        printf("Input str: ");
        //gets(buf);
        fgets(buf, LENGTH, stdin);
        send(sock_fd, buf, strlen(buf)+1, 0);
        if(!strncmp(buf, "exit", 4)) 
        {
            break;
        }
    }

    close(sock_fd);
}

编译链接执行: 先启动服务端, 然后在其它终端启动客户端. 执行结果如下:

技术分享

技术分享

技术分享

技术分享

技术分享

以上是关于socket接口多线程数据传输的主要内容,如果未能解决你的问题,请参考以下文章

Linux:TCP Socket编程(代码实战)

102.tcp实现多线程连接与群聊

多线程和Socket套接字

一个Socket能否被多线程写入

Linux-TCP编程流程-Socket编程-单线程实现TCP客户端和服务端交互-多进程实现TCP客户端和服务端交互

java代码实现socket接口通讯(堵塞I/O)