【发布时间】:2017-03-07 13:21:36
【问题描述】:
我有一个在 C 中使用套接字的多线程客户端-服务器架构。
Client.c
sockfd = socket(AF_INET, SOCK_STREAM, 0);
address.sin_family = AF_INET;
address.sin_addr.s_addr=inet_addr("127.0.0.1");
address.sin_port = 9734;
len = sizeof(address);
result = connect(sockfd, (struct sockaddr *)&address, len);
if(result==-1) {
perror("oops: client1");
return 1;
}
while(1) {
printf("Enter a string: ");
scanf("%s", str);
if(strcmp(str,"exit") == 0) close(sockfd); //At this point server terminates
write(sockfd, str, 100);
read(sockfd, str, 100);
printf("from server = %s\n", str);
}
Server.c
int main() {
int server_sockfd, client_sockfd;
int server_len, client_len;
struct sockaddr_in server_address, client_address;
server_sockfd = socket(AF_INET, SOCK_STREAM, 0);
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = inet_addr("127.0.0.1");
server_address.sin_port = 9734;
server_len = sizeof(server_address);
bind(server_sockfd, (struct sockaddr *)&server_address, server_len);
listen(server_sockfd, 100);
while( (client_sockfd = accept(server_sockfd,(struct sockaddr*)&client_address, &client_len)) ) {
// client_len = sizeof(client_address);
// client_sockfd = accept(server_sockfd,(struct sockaddr*)&client_address, &client_len);
pthread_t sniffer_thread;
int *new_sock = malloc(sizeof(int *));
*new_sock = client_sockfd;
if( pthread_create( &sniffer_thread , NULL , connection_handler , (void*) new_sock) < 0)
{
perror("could not create thread");
return 1;
}
printf("New thread assigned\n");
}
// close(server_sockfd);
}
void *connection_handler(void *sock) {
int client_sockfd = *(int *)sock;
char str[100];
while(1) { // If I remove this while loop, it works fine
printf("server waiting\n");
read(client_sockfd, str, 100);
write(client_sockfd, str, 100);
}
}
基本上这个想法是让服务器连续运行,新客户端可以根据需要连接和断开连接。
问题在于,一旦客户端被Ctrl+C 中断或发送“退出”消息,客户端就会终止,但服务器也会终止。服务器不应终止,而是侦听大多数传入的套接字请求。
有人可以就我到底做错了什么提供一些指导吗?我不希望分叉新进程或使用select()。它必须是多线程解决方案。
更新:
我对代码进行了一些更改,主要是添加了更多错误检查等。如果我在server.c 中删除线程连接处理程序中的while 循环,则服务器不会与客户端终止,这正是我想要的。但是我不想删除while循环,因为这意味着服务器和客户端只能在套接字自动关闭之前发送一条消息。
【问题讨论】:
-
与您的问题无关,但您的程序中存在内存泄漏。以及其他资源泄漏,因为理论上您可以创建无限数量的线程,这些线程将耗尽您的所有资源。完成后,您需要加入线程。
-
关于您的问题,您永远不会在任何地方检查错误或关闭的连接。如果连接关闭,则
read将返回0。尝试进一步使用关闭的套接字会导致错误。 -
您也没有以空值终止您的字符串或声明它们足够大以适应 NUL。
-
我将来会重构代码来处理这些问题。现在我唯一的问题是当与第一个客户端的连接关闭时服务器终止,由于你提到的原因,这似乎没有发生
-
顺便说一下,
client_len应该在每次调用accept之前初始化。
标签: c multithreading sockets client-server