【发布时间】:2017-05-20 12:07:21
【问题描述】:
(这个问题是thisdreadful question的续集)
我已经设法用我损坏的代码解决问题,并让它使用线程为多个客户端工作。
服务器:
#define SOCK_PATH "avg_socket"
int numofclients=0;
int numofrequests=0;
pthread_mutex_t MUT=PTHREAD_MUTEX_INITIALIZER;
void *find_average (void *arg)
{
int so = (int) arg;
int done;
printf("Connected.\n");
done = 0;
do {
int i=0;
int numofelements=0;
int sum=0;
float avg;
...
...
...
pthread_mutex_lock(&MUT);
numofrequests++;
pthread_mutex_unlock(&MUT);
printf("\n\nNumber of requests: %d \n", numofrequests);
printf("Number of clients: %d \n", numofclients);
} while (!done);
close(so);
pthread_exit(NULL);
}
int main(void)
{
int s, s2, i, t, len;
struct sockaddr_un local, remote;
pthread_t thread[50];
if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
}
local.sun_family = AF_UNIX;
strcpy(local.sun_path, SOCK_PATH);
unlink(local.sun_path);
len = strlen(local.sun_path) + sizeof(local.sun_family);
if (bind(s, (struct sockaddr *)&local, len) == -1) {
perror("bind");
exit(1);
}
if (listen(s, 5) == -1) {
perror("listen");
exit(1);
}
i=0;
for(;;) {
printf("Waiting for a connection...\n");
t = sizeof(remote);
if ((s2 = accept(s, (struct sockaddr *)&remote, &t)) == -1) {
perror("accept");
exit(1);
}
numofclients++; //counting the number of clients
pthread_create(&(thread[i++]), NULL, find_average, (void *)s2);
}
return 0;
}
客户:
#define SOCK_PATH "avg_socket"
int main(void)
{
int i, s, t, len, done;
struct sockaddr_un remote;
if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
}
printf("Trying to connect...\n");
remote.sun_family = AF_UNIX;
strcpy(remote.sun_path, SOCK_PATH);
len = strlen(remote.sun_path) + sizeof(remote.sun_family);
if (connect(s, (struct sockaddr *)&remote, len) == -1) {
perror("connect");
exit(1);
}
printf("Connected.\n");
done = 0;
int yesorno=1;
do {
float avg;
char seq[100];
char str[100];
char avgstring[200];
printf("Give the sequence of integers: \n");
fgets(seq, 100, stdin);
...
...
...
printf("\nWanna Continue? (1/0) :");
scanf("%d", &yesorno);
getchar();
if(!yesorno)
done=1;
} while (!done);
close(s);
return 0;
}
(有兴趣的人可以使用完整代码here)
但是现在,每次我关闭来自一个客户端的连接时,服务器也会关闭。
如上所示,客户端 3 关闭与服务器的连接,服务器本身同时关闭,而不是等待连接或客户端请求。
在我看来,服务器上的close(so) 似乎有些不对劲。我试图将它移动到循环中,例如here,但这只会在服务器上造成无限循环。
所以问题是,如何在客户端关闭时保持多线程服务器处于活动状态?
【问题讨论】:
-
我建议使用调试器,跟踪代码以了解实际情况。
-
对于
recv()失败的两个极端情况(这会导致它返回-1或返回100此代码int checkresponse=recv(s, str, 100, 0); str[checkresponse]='\0';写出str的边界,并这样做调用臭名昭著的未定义行为。从那时起,任何事情都可能发生。你想解决这个问题。
标签: c multithreading sockets