我目前正在编写一个C服务器,其目标是使用pthread来处理客户端连接,所有工作完全正常,直到我引入pthreads。我在pthread上解雇了一个客户端,它被创建并运行良好;但是,它将不再从客户端的文件描述符中读取()。
我一直试图解决这个问题大约2个星期了。我已经包含了服务器代码(包括和排除pthreads。)和客户端处理程序代码的代码片段。
这是我的主服务器循环(pthreaded):
/*Sets up and runs the server. (MAX 10 CLIENTS)*/
void publicServer(void)
{
//Server locals
int serverSocket_fd;
int clientSocket_fd;
socklen_t serverLength;
socklen_t clientLength;
struct sockaddr_in serverAddress;
struct sockaddr_in clientAddress;
//Threading locals
pthread_t threadPool[20]; //Pool of threads, used in a FIFO fashion.
int threadPointer = 0; //Points to the location of the next available thread.
//Clear old sockets
puts("Unlinking server socket");
unlink("server_socket");
//Setup server socket
printf("Setting server socket properties..\n");
serverSocket_fd = socket(AF_INET, SOCK_STREAM, 0);
serverAddress.sin_family = AF_INET;
serverAddress.sin_addr.s_addr = htonl(INADDR_ANY);
serverAddress.sin_port = htons(5000);
serverLength = sizeof(serverAddress);
//Bind the socket
printf("Binding socket\n");
bind(serverSocket_fd, (struct sockaddr*)&serverAddress, serverLength);
//Create listener
listen(serverSocket_fd, 20);
//Main server loop
printf("Entering main loop\n");
while (1)
{
clientLength = sizeof(clientAddress);
//Accept connection
printf("Blocking for connection\n");
clientSocket_fd = accept(serverSocket_fd, (struct sockaddr*)&clientAddress, &clientLength);
//Handle Client
pthread_create(&threadPool[0], NULL, clientHandler, clientSocket_fd);
//Increment thread pointer
threadPointer++;
if (threadPointer == 20)
{
threadPointer = 0;
}
//End client
close(clientSocket_fd);
}
}
这是没有pthreads的服务器代码(工作正常。):
/*Sets up and runs the server. (MAX 10 CLIENTS)*/
void publicServer(void)
{
//Server locals
int serverSocket_fd;
int clientSocket_fd;
socklen_t serverLength;
socklen_t clientLength;
struct sockaddr_in serverAddress;
struct sockaddr_in clientAddress;
//Clear old sockets
puts("Unlinking server socket");
unlink("server_socket");
//Setup server socket
printf("Setting server socket properties..\n");
serverSocket_fd = socket(AF_INET, SOCK_STREAM, 0);
serverAddress.sin_family = AF_INET;
serverAddress.sin_addr.s_addr = htonl(INADDR_ANY);
serverAddress.sin_port = htons(5000);
serverLength = sizeof(serverAddress);
//Bind the socket
printf("Binding socket\n");
bind(serverSocket_fd, (struct sockaddr*)&serverAddress, serverLength);
//Create listener
listen(serverSocket_fd, 20);
//Main server loop
printf("Entering main loop\n");
while (1)
{
clientLength = sizeof(clientAddress);
//Accept connection
printf("Blocking for connection\n");
clientSocket_fd = accept(serverSocket_fd, (struct sockaddr*)&clientAddress, &clientLength);
//Handle Client
clientHandler(clientSocket_fd);
//End client
close(clientSocket_fd);
}
}
这是客户端处理程序代码:
/*
* Handles the client's request.
* <int : client_fd> Client's file descriptor.
*/
void *clientHandler(int client_fd)
{
char request = ' ';
puts("Waiting for request");
read(client_fd, &request, 1);
//Determine what to do for user
if (request == '1') //Output current temp and pressure
{
outputCurrentTemperaturePressure(client_fd);
}
else if (request == '2') //Begin regular sampling of temp and pressure
{
startSampling();
}
else if (request == '3') //Stop regular sampling of temp and pressure
{
stopSampling();
}
else if (request == '4') //Clear the EEPROM
{
eraseEEPROM();
}
else if (request == '5') //Retrieve all stored temperature and pressure values
{
outputSavedTempPressValues(client_fd);
}
else if (request == '6') //Retrieve a certain number of temperature and pressure values
{
outputLastNTempPressValues(client_fd);
}
else if (request == '7') //Output current noise level
{
outputCurrentNoiseLevel(client_fd);
}
close(client_fd);
pthread_exit(1);
}
当我尝试从客户端读取时,问题出在clientHandler方法的第6行。在pthread上运行时,它始终读为0。但是,当没有pthreads运行时,它会读取正确的值。我希望有人可以帮忙解决这个问题,因为它让我很困惑。
提前致谢, 安迪
答案 0 :(得分:0)
只是在线程中关闭客户端socket_fd,而不是主函数
while (1)
{
clientLength = sizeof(clientAddress);
//Accept connection
printf("Blocking for connection\n");
clientSocket_fd = accept(serverSocket_fd, (struct sockaddr*)&clientAddress, &clientLength);
//Handle Client
pthread_create(&threadPool[0], NULL, clientHandler, clientSocket_fd);
//Increment thread pointer
threadPointer++;
if (threadPointer == 20)
{
threadPointer = 0;
}
//End client
/* remove close(clientSocket_fd) from here */
}
当你在while中运行新线程时,循环仍会关闭cliend文件描述符,这就是read()
无效的原因
答案 1 :(得分:0)
据我所知,pthread入口点必须有一个void *参数。你定义clientHandler的方式似乎是错误的。读这个: http://timmurphy.org/2010/05/04/pthreads-in-c-a-minimal-working-example/
答案 2 :(得分:0)
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
pthread_create(&threadPool[0], NULL, clientHandler, (void*)&clientSocket_fd);
void *clientHandler(void *args) {
int client_fd = *((int*) args);