多线程服务器无法处理多个客户端

时间:2018-05-27 18:46:49

标签: c linux sockets unix

我正在开发一个简单的服务器 - 客户端程序,客户端向服务器发送一个号码,然后服务器将号码发回。
我正在尝试实现多线程,以便多个客户端可以发送数字 问题是,当第二个客户端连接时,第一个客户端会在即将接收数据时冻结 到目前为止,我尝试了很多东西,但没有任何效果 如果有人可以帮我,我会在下面发布我的代码。

这是服务器:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include<string.h>    //strlen
#include<sys/socket.h>
#include<arpa/inet.h> //inet_addr
#include<unistd.h>    //write
#include<fcntl.h> //close
void *thread_function(void *arg);

int socket_desc , client_sock , c , read_size;
struct sockaddr_in server , client;
char client_message[20000]="0";
int len=256;
int i=0;
char message[] = "Hello World";

int main() {
    int res;
    pthread_t a_thread;
    void *thread_result;

    //Create socket
    socket_desc = socket(AF_INET , SOCK_STREAM , 0);
    if (socket_desc == -1)
    {
        printf("Could not create socket");
    }
    puts("Socket created");

    //Prepare the sockaddr_in structure
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = INADDR_ANY;
    server.sin_port = htons( 8888 );

    //Bind
    if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
    {
        //print the error message
        perror("bind failed. Error");
        return 1;
    }
    puts("bind done");

    //Listen
    listen(socket_desc , 3);

    //Accept and incoming connection
    puts("Waiting for incoming connections...");

    for(;;){
        c = sizeof(struct sockaddr_in);
        //accept connection from an incoming client
        client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c);

        if (client_sock < 0)
        {
            perror("accept failed");
            return 1;
        }
        puts("Connection accepted");
        printf("Client connected with IP: %s\n", inet_ntoa(client.sin_addr));


        pthread_create(&a_thread, NULL, thread_function, (void *)message);

        pthread_detach(a_thread);

    }
    //  return 0;
}
//-------------------------------------------------
//-------------------------------------------------
void *thread_function(void *arg) {
    //Receive a message from client
    while((read_size = recv(client_sock , client_message , 2000 ,0)) > 0 )
    {
        len=strlen(client_message);
        //Send the message back to client

        send(client_sock , client_message ,2000,0);
        fflush(stdin);
        fflush(stdout);
        puts(client_message);
        strncpy(client_message,"0",sizeof(client_message) - 1);
    }
}

这是客户:

#include<stdio.h> //printf
#include<string.h>    //strlen
#include<sys/socket.h>    //socket
#include<arpa/inet.h> //inet_addr
#include<unistd.h>    //write
#include<fcntl.h> //close

int main(int argc , char *argv[])
{
    int n;
    char sn[200];
    int sock;
    struct sockaddr_in server;
    char message[2000] , server_reply[2000];
    int i=0;
    char user[20];
    char pass[20];
    int sig;
    //Create socket
    sock = socket(AF_INET , SOCK_STREAM , 0);
    if (sock == -1)
    {
        printf("Could not create socket");
    }
    puts("Socket created");

    server.sin_addr.s_addr = inet_addr("127.0.0.1");
    server.sin_family = AF_INET;
    server.sin_port = htons( 8888 );

    //Connect to remote server
    if (connect(sock , (struct sockaddr *)&server , sizeof(server)) < 0)
    {
        perror("connect failed. Error");
        return 1;
    }

    puts("Connected\n");

    //keep communicating with server
    n=1;
    while(1)
    {
        printf("Enter message : ");

        strncpy (message,"0",sizeof(message) - 1);
        // itoa(n, sn, 10);
        sprintf(sn, "%d", n);
        strcpy(message,sn);
        //gets(message);

        //Send some data
        send(sock , message , strlen(message) , 0);
        recv(sock , server_reply , 2000 , 0);
        puts("Server reply :");
        puts(server_reply);
        n++;
    }

    close(sock);
    return 0;
}

1 个答案:

答案 0 :(得分:0)

您只有一个变量<main> <article> <h1>Main content</h1> </article> <aside> Crouching Tiger, Hidden Text </aside> </main>,它在所有线程之间共享。这意味着每个新的client_sock将使用新的客户端套接字替换此变量,以便基本上所有线程都可以在同一个(最新的)套接字上工作,并且没有线程可以处理先前建立的套接字。