是否可以在 fd_set 中打印套接字的状态?
假设我有这个代码:
int main(int argc, char * argv[]) {
int sockfd, newfd, i;
struct sockaddr_un sv_addr, cli_addr;
int sv_len, cli_len;
fd_set testmask, mask;
if ((sockfd = socket(AF_UNIX,SOCK_STREAM,0))<0) {
perror("Error creating socket");
exit(-1);
}
bzero((char*)&sv_addr,sizeof(sv_addr));
sv_addr.sun_family = AF_UNIX;
strcpy(sv_addr.sun_path,UNIXSTR_PATH);
sv_len=sizeof(sv_addr.sun_family)+strlen(sv_addr.sun_path);
unlink(UNIXSTR_PATH);
if(bind(sockfd,(struct sockaddr*)&sv_addr,sv_len)<0) {
perror("Error binding socket");
exit(-1);
}
listen(sockfd, 15);
FD_ZERO(&testmask);
FD_SET(sockfd,&testmask);
for(;;) {
mask = testmask;
select(MAXSOCKS,&mask,0,0,0);
if(FD_ISSET(sockfd,&mask)) {
cli_len = sizeof(cli_addr);
newfd = accept(sockfd, (struct sockaddr*)&cli_addr, &cli_len);
echo(newfd);
close(newfd);
}
for(i=0;i<MAXSOCKS;i++) {
if (FD_ISSET(i, &mask)) {
close(i);
FD_CLR(i, &mask);
}
}
}
close(sockfd);
return 0;
}
我的程序中一切正常(它是一个回显服务器,客户端发送一行,服务器只是回显它)。 我想在选择调用之后,在服务器终端中打印类似的内容; 00011011011 这意味着,打印准备好处理的袜子。 无论如何我可以做到这一点吗?
另外,在 for 循环结束时我应该做什么?我知道我必须以某种方式清除 fd_set。我这样做的方式(小for循环关闭和FD_CLR fd_set)是否正确?或者我应该用另一种方式做?
PS:抱歉我的英语或任何错误。 :)
[这并没有回答你的问题,但是指的是对OP的评论并且对于另一条评论来说太长了]
man select
:
nfds 是三个集合中编号最大的文件描述符,再加 1。
nfds
是不是 常数!手册页不读作:
[...] 最大的 可能 编号的文件描述符 [...]
nfds
必须动态地描述传递给 fd_set
的 select()
。
int nfds = sockfd + 1;
for(;;) {
mask = testmask;
select(nfds, &mask, 0, 0, 0);
if(FD_ISSET(sockfd,&mask)) {
cli_len = sizeof(cli_addr);
newfd = accept(sockfd, (struct sockaddr*)&cli_addr, &cli_len);
echo(newfd);
close(newfd);
}
for(i = 0; i < nfds; ++i) {
if (FD_ISSET(i, &mask)) {
close(i);
FD_CLR(i, &mask);
}
}
}
调整
nfds
,将每个套接字描述符添加到传递给fd_set
的select()
。
选择调用后,您检查了 sockfd。如果这是真的,则意味着客户端尝试连接您的服务器。然后您接受连接。
newfd = 接受(sockfd, (struct sockaddr*)&cli_addr, &cli_len);
newfd 是您知道的客户端和服务器之间的 fd 号。这里,你仍然没有读取clientfd(newfd)数据。连接接受后,您可以像这样读取 clentfd 上的数据
读取(newfd,缓冲区,sizeof(缓冲区))
您从客户端发送的数据,现在在缓冲区中。那么也许你可以在 clientfd 中 echo 或 write() 。
您的代码发送到客户端,服务器和客户端之间的FD号码。
如果始终监听客户端,在接受连接后,您必须在 readfds(代码中的掩码)中设置客户端 fd,如 FDSET(newfd,&mask)
然后您就可以随时聆听客户的声音