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

标签 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;
}

最佳答案

您只有一个变量 client_sock,它在所有线程之间共享。这意味着每个新的 accept 都会用新的客户端套接字替换这个变量,这样基本上所有线程都将在同一个(最新的)套接字上工作,并且没有线程会处理以前建立的套接字。

关于c - 多线程服务器无法处理多个客户端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50555403/

相关文章:

使用调试寄存器断点和向量化异常处理捕获堆栈跟踪

c - XOR交换算法和使用第三个变量交换之间有什么区别吗?

Linux (Debian 8 Jessie) HRTimer - 内核 - 闰秒

python - Ntrip 客户端未收到 RTCM 更正

android - 不满意的链接错误 - 找不到库

c - IEEE-754 在 C 中 float

linux - Flume 在 Linux 中运行失败

Linux——解析数据,用什么语言

java - 由 : java. io.IOException 引起:长度 1279873876 超出限制:26

linux - 使用 shell 命令将数据汇集到守护进程的非守护进程中