我基本上有一个服务器设置,我接受新客户端(UNIX),我正在使用select()命令等待文件描述符上的活动,但我不知道如何从客户端写入然后在服务器端阅读
FD_ZERO(&readfds);
FD_SET(server_sockfd, &readfds);
FD_SET(STDIN_FILENO, &readfds);
while (1) {
testfds = readfds;
select(4 + MAXCLIENTS, &testfds, NULL, NULL, NULL);
for (fd = 0; fd < 4 + MAX_CLIENTS; fd++) {
if (FD_ISSET(fd, &testfds)) {
if (fd == server_sockfd) { /* new connection request */
client_sockfd = accept(server_sockfd, NULL, NULL);
if (num_clients < MAXCLIENTS) {
FD_SET(client_sockfd, &readfds);
num_clients++;
} else {
sprintf(message, "XSorry, too many clients. Try again later.\n");
write(client_sockfd, message, strlen(message));
close(client_sockfd);
}
} else if (fd == STDIN_FILENO) {
fgets(kb_message, BUFSIZ + 1, stdin);
if (strcmp(kb_message, "quit\n") == 0) {
sprintf(message, "XServer is shutting down.\n");
for (fd2 = 4; fd2 < 4 + MAX_CLIENTS; fd2++) {
if (FD_ISSET(fd2, &readfds)) {
write(fd2, message, strlen(message));
close(fd2);
}
}
close(server_sockfd);
exit(EXIT_SUCCESS);
} else {
sprintf(message, "M%s", kb_message);
for (fd2 = 4; fd2 < 4 + MAX_CLIENTS; fd2++)
if (FD_ISSET(fd2, &readfds))
write(fd2, message, strlen(message));
}
} else { /* client leaving */
close(fd);
FD_CLR(fd, &readfds);
num_clients--;
}
}
}
}
我如何处理来自客户端的写入请求然后回写给它们,它是否在“其他”下面,我如何检查客户端是退出还是写入。
由于
答案 0 :(得分:2)
select(2)
最常见的错误是 没有重新初始化描述符集 ,因为第二个,第三个和第四个参数是输入 - 输出参数。
设置fd_set
,在外部循环之前读取,向其添加侦听套接字描述符,进入循环,制作此fd_set
的副本并给出复制到select(2)
。当新连接到达时,将其描述符添加到原始 fd_set
。关闭套接字相同(read(2)
上的错误或EOF) - 从原始 fd_set
中删除描述符。
希望这有帮助。
答案 1 :(得分:1)
您认为在“其他”块中需要读取代码是正确的。如果文件描述符触发并且它不是标准输入或“连接”描述符,那么它是您尝试向您发送数据的客户之一。当在select中触发其中一个文件描述符时,需要在该描述符上调用“read”以将数据读入缓冲区。 read命令将返回读取的字节数。如果这是一个正数,则表示客户端已向您发送数据。如果它为零,则表示客户端已结束与服务器的TCP连接。
else块看起来像:
else
{
//Existing connection has data for us to read
if((nBytes = read(fd, buffer, MAXBUFFER)) <= 0)
{
if(nBytes == 0)
{
//Actually, its sending us zero bytes, connection closed
printf("Socket %d hung up\n", fd;
}
else
printf ("Read Error"\n)
}
另外,按照上面的Nikolai N Fetissov的建议,确保当客户端连接时将fd存储在永久fd_set结构中,因为正在使用的那个正在被select调用修改。
答案 2 :(得分:0)
您的问题可能是您有一个名为read
的变量。它将掩盖你需要使用的一个hte函数 - read()
系统调用以从套接字中获取数据。客户端将其放入write()
。您可能还想检查select()
的返回值,它将告诉您有多少文件描述符可供阅读。然后,您可以使用FD_ISSET()
检查哪些。看起来你已经在做那个部分了(除了你似乎正在检查错误的变量?)...只需在该文件描述符上调用read()
以获取客户端编写的数据。
答案 3 :(得分:0)
else
{
bzero(buf,100);
n=read(i,buf,100); // Read the client message
buf[n]='\0';
if(n==0) // Check the client is closed or not
{
printf("%d is closed\n",i);
close(i);
FD_CLR(i, &master);
if(i==fdmax)
fdmax--;
}
else
{
n=strlen(buf);
write(1,buf,n);
fflush(stdout);
write(1,"Enter the message\n",18);
bzero(buf,100);
read(0,buf,100);
buf[n]='\0';
write(i,buf,n);
fflush(stdout);
}
}
注意: 接受客户端后,在fd集中添加客户端。 然后从客户端读取消息 如果消息等于0,则关闭客户端。 如果要使用客户端fd将消息发送到客户端,则可以发送到客户端