select() 之后的奇怪顺序(使用 FD_SET())
Weird order after select() (with FD_SET())
我正在开发一个多客户端 Unix Domain Socket 以通过多个进程传输数据。我找到了一些实现每个客户端和东西之间聊天的代码,但我希望一旦客户端向服务器发送内容,服务器回复并且客户端断开连接。
话虽如此,我不想要 while(fgets())
但我想要(在客户端):
int main() {
int sockfd;
struct sockaddr_un remote;
fd_set readfds;
char buf[1024];
char buf2[1024];
int len;
sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
remote.sun_family = AF_UNIX;
strcpy(remote.sun_path, SOCK_PATH);
len = strlen(remote.sun_path) + sizeof(remote.sun_family);
if(connect(sockfd, (struct sockaddr*)&remote, len) == -1)
/* handle error */
FD_ZERO(&readfds);
FD_SET(0, &readfds);
FD_SET(sockfd, &readfds);
if(select(sockfd+1, &readfds, NULL, NULL, NULL) == -1)
/* handle error */
if(FD_ISSET(0, &readfds)) {
fgets(buf, 1024, stdin);
if(write(sockfd, buf, 1024) <= 0)
/* handle error */
}
if(FD_ISSET(sockfd, &readfds)) {
if(read(sockfd, &buf2, 1024) <= 0)
/* handle error */
}
printf("%s\n", buf2);
close(sockfd);
}
按此顺序,如果我在 connect()
之后做所有事情两次(使用循环),它会起作用,但我只想做一次。没有这个循环,我的服务器(它是一个守护进程)崩溃了,我不知道为什么。
此外,我从上面的代码中添加了 printf()
以了解其工作原理:
(...)
printf("before select\n");
fflush(stdout);
if(select(sockfd+1, &readfds, NULL, NULL, NULL) == -1)
/* handle error */
printf("before select\n");
fflush(stdout);
if(FD_ISSET(0, &readfds)) {
fgets(buf, 1024, stdin);
if(write(sockfd, buf, 1024) <= 0)
/* handle error */
}
(...)
我有这个输出:
before select
"input to fgets"
after select
而且我不明白为什么我在 "after select" 之前输入。这对我来说没有任何意义,因为我在 printf()
.
之后调用 fgets()
我希望这是可以理解的。
我的代码有什么问题?我错过了什么吗?
第一次通过时,您在服务器响应之前调用 select()
。结果是 sockfd
无法读取。
在您的情况下,客户可能不需要 sockfd
上的 select()
。你知道如果你向服务器写了一些东西你想要等待回复,对吧?
我正在开发一个多客户端 Unix Domain Socket 以通过多个进程传输数据。我找到了一些实现每个客户端和东西之间聊天的代码,但我希望一旦客户端向服务器发送内容,服务器回复并且客户端断开连接。
话虽如此,我不想要 while(fgets())
但我想要(在客户端):
int main() {
int sockfd;
struct sockaddr_un remote;
fd_set readfds;
char buf[1024];
char buf2[1024];
int len;
sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
remote.sun_family = AF_UNIX;
strcpy(remote.sun_path, SOCK_PATH);
len = strlen(remote.sun_path) + sizeof(remote.sun_family);
if(connect(sockfd, (struct sockaddr*)&remote, len) == -1)
/* handle error */
FD_ZERO(&readfds);
FD_SET(0, &readfds);
FD_SET(sockfd, &readfds);
if(select(sockfd+1, &readfds, NULL, NULL, NULL) == -1)
/* handle error */
if(FD_ISSET(0, &readfds)) {
fgets(buf, 1024, stdin);
if(write(sockfd, buf, 1024) <= 0)
/* handle error */
}
if(FD_ISSET(sockfd, &readfds)) {
if(read(sockfd, &buf2, 1024) <= 0)
/* handle error */
}
printf("%s\n", buf2);
close(sockfd);
}
按此顺序,如果我在 connect()
之后做所有事情两次(使用循环),它会起作用,但我只想做一次。没有这个循环,我的服务器(它是一个守护进程)崩溃了,我不知道为什么。
此外,我从上面的代码中添加了 printf()
以了解其工作原理:
(...)
printf("before select\n");
fflush(stdout);
if(select(sockfd+1, &readfds, NULL, NULL, NULL) == -1)
/* handle error */
printf("before select\n");
fflush(stdout);
if(FD_ISSET(0, &readfds)) {
fgets(buf, 1024, stdin);
if(write(sockfd, buf, 1024) <= 0)
/* handle error */
}
(...)
我有这个输出:
before select
"input to fgets"
after select
而且我不明白为什么我在 "after select" 之前输入。这对我来说没有任何意义,因为我在 printf()
.
fgets()
我希望这是可以理解的。 我的代码有什么问题?我错过了什么吗?
第一次通过时,您在服务器响应之前调用 select()
。结果是 sockfd
无法读取。
在您的情况下,客户可能不需要 sockfd
上的 select()
。你知道如果你向服务器写了一些东西你想要等待回复,对吧?