gpt4 book ai didi

c - TCP Linux 服务器在第一次接受后锁定

转载 作者:行者123 更新时间:2023-11-30 17:27:49 26 4
gpt4 key购买 nike

我正在用 C 语言编写一个 TCP 客户端。按照几个教程,我编写了代码,但它只能接受与服务器的第一次连接。

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <arpa/inet.h> //inet_addr for INADDR_ANY
#include <string.h> //for splitting (strtok)
#include <pthread.h> //thread library
#include <time.h>
#include <unistd.h> //for function close()

void* SocketHandler(void*);


int main(void) {
//socket parameters
int server_socket_desc;
int clientAddressLength = sizeof(struct sockaddr_in);
struct sockaddr_in server_addr, client_addr;

const unsigned short int PORT_NUMBER = 8963;
server_socket_desc = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (server_socket_desc < -1) {
printf("Could not create socket");
}
puts("Socket created");

//Prepare the sockaddr_in structure
server_addr.sin_family = AF_INET; //it should be always set to AF_INET
//set the server address
server_addr.sin_addr.s_addr = inet_addr("192.168.123.240");
//server_addr.sin_addr.s_addr = inet_addr("31.185.101.35");
//server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
server_addr.sin_port = htons(PORT_NUMBER);

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

//Listen
listen(server_socket_desc, 10);

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

//accept connection from an incoming client
while (1) {
int *temp_socket_desc = (int*) malloc(sizeof(int));
if ((*temp_socket_desc = accept(server_socket_desc,
(struct sockaddr *) &client_addr,
(socklen_t*) &clientAddressLength)) != -1) {

printf("----------\nConnection accepted \n");
sleep(1);
pthread_t thread_id;
int *client_socket_desc = (int*) malloc(sizeof(int));
client_socket_desc = temp_socket_desc;

pthread_create(&thread_id, NULL, &SocketHandler,
(void*) client_socket_desc);
//if thread has not terminated, pthread_detach() shall not cause it to terminate
pthread_detach(thread_id);
puts("handler assigned");

} else
puts("connection refused");

}

close(server_socket_desc);
//mysql_close(mysql_conn);
return 0;
}

/*
* This will handle connection for each client
* */
void* SocketHandler(void* lp) {
int *csock = (int*) lp;

char buffer[128];
int buffer_len = 128;
int bytecount;
memset(buffer, 0, buffer_len);
if ((bytecount = read(*csock, buffer, buffer_len) == -1)) {
fprintf(stderr, "Error receiving data\n");
close(*csock);
return 0;
}
printf("Received bytes %d\nReceived string \"%s\"\n", bytecount, buffer);

close(*csock);
free(csock);
puts("exiting thread");
//pthread_exit(0);
return 0;
}

我暂时解决了在 while 循环之后插入 sleep() 的问题,但这是一个非常糟糕的解决方案。有人可以解释一下为什么代码在没有 sleep 的情况下无法工作吗?

最佳答案

处理 client_socket_desc 时出现问题:

您只分配一次。所有线程将获得相同的指针。因此稍后的接受将覆盖早期线程的套接字描述符值。

尝试以下更改,为每个线程分配自己的内存块:

int fd = accept( server_socket_desc, (struct sockaddr *) &client_addr, (socklen_t*)                
&clientAddressLength)
if ( fd != -1 )
{
pthread_t thread_id;
int *client_socket_desc = malloc(sizeof(int));

*client_socket_desc = fd;

pthread_create(&thread_id, NULL, &SocketHandler,(void*) client_socket_desc);
...

或者当然您必须为 malloc 和 pthread_create 添加错误处理。并且在不再需要时释放分配的内存。

我不明白为什么while循环中有下面的代码:

if(send(*client_socket_desc,buffer,1,MSG_NOSIGNAL)>0)
{
puts("closing client socket");
close(*client_socket_desc);
}

关闭客户端处理程序线程中的客户端套接字。

关于c - TCP Linux 服务器在第一次接受后锁定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26257666/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com