C,Socket,pthread:read不适用于新线程

时间:2015-08-06 23:05:26

标签: c sockets

我正在使用线程在C中创建客户端 - 服务器程序。 我有这个问题:在服务器上,在线程#1(number_one)上,函数“read”工作正常。但是当我创建另一个线程#2(number_two)时,就会出现问题。参数以正确的方式传递(我认为)。

- > thread number_one

...   
        char message[256];
        int new_connection=accept(master_sock,NULL,NULL);
        pthread_t temp

        if(pthread_create(&temp , NULL , number_two , (void*) &new_connection))
        {
            perror("pthread_create failed");
            exit(-2);
        }
        else
        {
            puts("number_two created");
            if(read(new_connection, message, 256) > 0)
            printf("Message from client is %s", message);
        }
        if(pthread_detach(temp))
        {
            perror("detach failed");
            exit(-3);
        }

...

--->线号number_two

void *number_two(void *sock_desc)
{
    int sock = *(int*)sock_desc;

    int read_size;
    char client_message[2000];  

    read_size=read(sock, client_message, 256);
    client_message[read_size]='\0'; 

    return 0;
}

在“number_one”中,read等待来自客户端的输入,然后正确设置缓冲区“message”。

在“number_two”中,read不会等待客户端,也不会将缓冲区设置为“client_message”。

谢谢。

1 个答案:

答案 0 :(得分:0)

请试试我的代码?它有效,我认为它与你的代码是一样的。

#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
#include <pthread.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <netdb.h>

#define INVALID_SOCKET_FD  (-1)



int create_tcp_server_socket(unsigned short port, bool bind_local, int backlog,
        char *caller_name)
{
    int socket_fd = INVALID_SOCKET_FD;
    struct sockaddr_storage server_addr;

    unsigned int yes = 1;

    // just try ipv4
    if (socket_fd < 0 && (socket_fd = socket(PF_INET, SOCK_STREAM, 0)) >= 0) {
        struct sockaddr_in *s4 = (struct sockaddr_in *)&server_addr;
        setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));
        memset(&server_addr, 0, sizeof(server_addr));
        s4->sin_family = AF_INET;
        s4->sin_port = htons(port);
        if (bind_local)
            s4->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
        else
            s4->sin_addr.s_addr = htonl(INADDR_ANY);

        if (bind(socket_fd, (struct sockaddr *)&server_addr,
                sizeof(server_addr)) < 0) {
            close(socket_fd);
            printf("Server: Failed to bind ipv4 server socket.\n");
            return INVALID_SOCKET_FD;
        }
    }
    else if (socket_fd < 0) {
        printf("Server: Failed to create server socket.\n");
        return INVALID_SOCKET_FD;
    }

    if (listen(socket_fd, backlog) < 0) {
        close(socket_fd);
        printf("Server: Failed to set listen.\n");
        return INVALID_SOCKET_FD;
    }

    return socket_fd;
}



pthread_t temp;



void *number_two(void *sock)
{
    char buf[1024];
    int fd = *(int *)sock;
    int nread = read(fd, buf, 1024);
    write(STDOUT_FILENO, buf, nread);

    return NULL;
}



int main()
{
    pid_t pid;
    if ((pid = fork()) < 0) {
    }
    else if (pid > 0) {  // parent, server
        char buf[1024];
        int fd = create_tcp_server_socket(8787, false, 10, "zz");
        int new_fd = accept(fd, NULL, 0);
        pthread_create(&temp, NULL, number_two, (void *)&new_fd);
    }
    else {  // child, client
        uint32_t ip;
        struct hostent *hp = gethostbyname("localhost");
        memcpy(&ip, hp->h_addr_list[0], hp->h_length);

        struct sockaddr_in server_addr;
        memset((char *)&server_addr, 0, sizeof(server_addr));
        server_addr.sin_family = AF_INET;
        server_addr.sin_addr.s_addr = ip;
        server_addr.sin_port = htons(8787);

        int fd = socket(AF_INET, SOCK_STREAM, 0);
        connect(fd, (struct sockaddr *)&server_addr, sizeof(server_addr));

        write(fd, "abcd", 4);
    }

    pause();
    return 0;
}