套接字编程:为什么recv()和read()的行为不一样?
我使用 select()
从标准输入接收数据。
代码如下:
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>
int main()
{
fd_set rfds;
struct timeval tv;
int retval;
char buf[100];
FD_ZERO(&rfds);
FD_SET(STDIN_FILENO, &rfds);
tv.tv_sec = 5;
tv.tv_usec = 0;
retval = select(1,&rfds,0,0,&tv);
if( retval == -1)
perror("select reset\n");
else if(retval == 0)
printf("timeout\n");
else
{
printf("data available\n");
if(FD_ISSET(STDIN_FILENO, &rfds))
{
//int ret = recv(STDIN_FILENO, buf, sizeof(buf), 0); // ret get -1.
int ret = read(STDIN_FILENO, buf, sizeof(buf)); // ret get correct data.
printf("buf: %s ret: %d\n", buf,ret);
}
}
return 0;
}
在这段代码中,recv()
总是返回-1
,但是read()
却能得到正确的数据。
我发现 read()
相当于 recv()
,但 flags
参数为 0
。那么为什么我的代码中 recv()
和 read()
的行为不一样呢?
I use select()
to receive data from stdin.
The code is here:
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>
int main()
{
fd_set rfds;
struct timeval tv;
int retval;
char buf[100];
FD_ZERO(&rfds);
FD_SET(STDIN_FILENO, &rfds);
tv.tv_sec = 5;
tv.tv_usec = 0;
retval = select(1,&rfds,0,0,&tv);
if( retval == -1)
perror("select reset\n");
else if(retval == 0)
printf("timeout\n");
else
{
printf("data available\n");
if(FD_ISSET(STDIN_FILENO, &rfds))
{
//int ret = recv(STDIN_FILENO, buf, sizeof(buf), 0); // ret get -1.
int ret = read(STDIN_FILENO, buf, sizeof(buf)); // ret get correct data.
printf("buf: %s ret: %d\n", buf,ret);
}
}
return 0;
}
In this code, recv()
will always return -1
, but read()
can get correct data.
I find that read()
is equivalent to recv()
with a flags
parameter of 0
. Why then are the behaviors of recv()
and read()
not the same in my code?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
因为
recv()
用于套接字,而不是像 stdin 这样的通用文件描述符。套接字可以像任何描述符一样对待,但描述符后面不一定有套接字(在 stdin 的情况下,它们没有)。在该特定代码段中,我怀疑如果您检查 errno ,它将具有 EINVAL 或类似值。
Because
recv()
is for use on sockets, not generic file descriptors like stdin. Sockets can be treated like any descriptor, but descriptors don't necessarily have a socket behind them (and in the case of stdin, they don't).In that particular piece of code, I suspect that if you check
errno
it will have a value ofEINVAL
or similar.查看手册页:
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
check out man page:
ssize_t recv(int sockfd, void *buf, size_t len, int flags);