gpt4 book ai didi

c - 使用 select() 系统调用监听标准输入和服务器

转载 作者:太空狗 更新时间:2023-10-29 11:06:01 24 4
gpt4 key购买 nike

我想使用选择系统调用来复用 STDIN 和 SOCKFD(连接到服务器),这样我必须同时监听 STDIN 和 SOCKFD,并且根据数据可供读取的位置,我必须进一步处理。

注意:#define STDIN 0

这就是我执行以下操作时发生的情况。

  • 我以通常的方式连接到服务器 [ socket() 然后 connect() ]
  • 我将 STDIN 和连接套接字描述符“SOCKFD”添加到用于读取的 fd_set(名为“readset”)。
  • 然后我调用 select()。
  • 使用 FD_ISSET 确定哪个 fd 已准备好读取。

此设置的问题是 FD_ISSET 对两个 fd 始终为真。连接到服务器后,我看到 FD_ISSET(sockfd, &readset) 始终为真,FD_ISSET(STDIN, &readset) 也始终为真,无论服务器是否正在发送数据,或者我是否正在从键盘输入数据。

我做错了什么?

/* 连接成功*/

FD_ZERO(&connset);

while(1) {

FD_SET(sockfd,&connset); /* add sockfd to connset */
FD_SET(STDIN,&connset); /* add STDIN to connset */
fdmax=sockfd;

if(select(fdmax+1,&readset,NULL,NULL,NULL)<0){
fprintf(stdout, "select() error\n");
exit(0);
}

/* select returned
* check which socket is set
*/

if(FD_ISSET(sockfd,&connset)) {

/*
* Server sends msglen
* client reads msg of length msglen
* client prints it to stdout
* client waits for next activity of its listen sockets
*/
size=4;
ptr=(char *)&msglen;
while(1) {
if((nread=recv(sockfd,ptr,size,0)),MSG_DONTWAIT) {
close(sockfd);
exit(0);
}
size-=nread;
ptr+=nread;
}
bytesToRead = ntohl(msglen);
readbuf = (char *)malloc(sizeof(char)*(bytesToRead+1));
ptr=readbuf;
while(1) {
nread=recv(sockfd,ptr,bytesToRead,MSG_DONTWAIT);
if(nread<=0) {
close(sockfd);
exit(0);
}
bytesToRead-=nread;
ptr+=nread;
}
/* msg read successfully */
*ptr='\0';
fprintf(stdout, "in: %s\n",readbuf);
free(readbuf);
}

if(FD_ISSET(STDIN,&connset)) {
/* data at STDIN */
fgets(buf,2,stdin); /* read the first newline char (< enter >) */
fprintf(stdout,"Enter msg: ");
fgets(buf,MAXLEN,stdin); /* read the msg */
buf[strlen(buf)-1]='\0';
msglen = htonl((uint32_t)(strlen(buf)-1));
ptr = (char *)&msglen;
bytesToSend = sizeof(uint32_t);
cnt = bytesToSend;
while(cnt>0) {
if((nsent=send(sockfd,ptr,cnt,0))>0) {
cnt-=nsent;
ptr+=nsent;
}
else {
fprintf(stdout,"send error\n");
exit(0);
}
}
ptr=buf;
bytesToSend=(uint32_t)(strlen(buf)-1);
cnt=bytesToSend;
while(cnt>0) {
if((nsent=send(sockfd,ptr,cnt,0))>0) {
cnt-=nsent;
ptr+=nsent;
}
else {
fprintf(stdout,"send error\n");
exit(0);
}
}
}
}
return 0;

最佳答案

什么是标准输入?在 <stdio.h> 中声明了标准输入, 是一个 FILE* 而不是文件描述符,因此不能在 fdset 和 STDIN_FILENO 中使用,它在 <unistd.h> 中定义。并且是一个文件描述符,因此可以与 fdsets 一起使用。

顺便说一句,在<stdio.h>还有一个函数 fileno()它返回 FILE* 的文件描述符(根据您的编译标志,您可能需要定义一些功能宏来获取声明)。

关于c - 使用 select() 系统调用监听标准输入和服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5360660/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com