'After the first child thread exits, the process ends in Linux socket
After the first child thread exits, the process ends in Linux socket. Please point the error,thanks. After I close the first client thread, the main process close,too. I don't know how to modify the code. The following is my whole codes.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/signal.h>
#include <fcntl.h>
#include <errno.h>
#include <pthread.h>
#define BUF_SIZE 1024
#define CONNECT_INFO 100
#define CLIENT_SIZE 100
int serv_port = 20000;
pthread_mutex_t mutex;
int clintQueue[CLIENT_SIZE];
int front = 0, rear = 0;
void error_handle(char *message);
void *read_func(void *clnt_sock);
int send_message(int socketFd, char *message, int len);
void error_handle(char *message)
{
perror(message);
exit(-1);
}
int send_message(int socketFd, char *message, int len)
{
pthread_mutex_lock(&mutex);
int ret = write(socketFd, message, len);
if (ret <= 0)
{
perror("write error");
}
pthread_mutex_unlock(&mutex);
return ret <= 0 ? 0 : 1;
}
void *read_func(void *arg)
{
// pthread_detach(pthread_self());
int clnt_sock = *(int *)arg;
char buf[BUF_SIZE];
int message_len;
while ((message_len = read(clnt_sock, buf, BUF_SIZE)) != 0)
{
buf[message_len] = 0;
printf("%s", buf);
send_message(clnt_sock, buf, message_len - 1);
memset(buf, 0, BUF_SIZE);
}
pthread_mutex_lock(&mutex);
printf("client %d[queue is %d]log out\n", clnt_sock, clintQueue[front]);
front++;
pthread_mutex_unlock(&mutex);
close(clnt_sock);
return NULL;
}
int main(int argc, char *argv[])
{
char clientInfo[CONNECT_INFO];
int serv_sock, clnt_sock;
socklen_t clnt_addr_len;
pthread_t read_id; //线程id
struct sockaddr_in serv_addr, clnt_addr;
pthread_mutex_init(&mutex, NULL);
serv_sock = socket(PF_INET, SOCK_STREAM, 0);
if (serv_sock < 0)
{
perror("serv_sock create failed!");
}
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(serv_port);
serv_addr.sin_addr.s_addr = INADDR_ANY;
if (bind(serv_sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
error_handle("bind fail");
}
else
{
puts("bind success");
}
if (listen(serv_sock, CLIENT_SIZE) < 0)
{
error_handle("listen fail");
}
else
{
puts("listen success");
}
while (1)
{
clnt_addr_len = sizeof(clnt_addr);
clnt_sock = accept(serv_sock, (struct sockaddr *)&clnt_addr, &clnt_addr_len);
if (clnt_sock < 0)
{
puts("clnt_sock < 0");
close(clnt_sock);
}
if (front == (rear + 1) % CLIENT_SIZE)
{
puts("client queue has flowed, connect failed");
close(clnt_sock);
}
else
{
memset(clientInfo, 0, sizeof(clientInfo));
pthread_mutex_lock(&mutex);
clintQueue[rear++] = clnt_sock;
pthread_mutex_unlock(&mutex);
// debug rear
printf("%d\n", rear);
puts("client queue add");
sprintf(clientInfo, "clientInfo[fd:%d, ip:%s, port:%d] has connected!", clnt_sock, inet_ntoa(clnt_addr.sin_addr), ntohs(clnt_addr.sin_port));
puts(clientInfo);
pthread_create(&read_id, NULL, read_func, (void *)&clnt_sock);
pthread_detach(read_id);
printf("thread %ld create success!\n", (pthread_t)read_id);
}
}
close(serv_sock);
pthread_mutex_destroy(&mutex);
return 0;
}
I want to use a main thread to control the connection, and the child threads to handle sending and receiving
Solution 1:[1]
On my computer, the application seems to behave fine:
florian@florian-desktop:~$ ./a.out
bind success
listen success
1
client queue add
clientInfo[fd:4, ip:127.0.0.1, port:33730] has connected!
thread 140353384478272 create success!
client 4[queue is 4]log out
2
client queue add
clientInfo[fd:5, ip:127.0.0.1, port:33732] has connected!
thread 140353384478272 create success!
this is a test
client 5[queue is 5]log out
I connected two telnet sessions to the application. I killed the first telnet immediatelly and the second telnet after sending out the message "this is a test".
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Florian Sc |