套接字编程:为什么recv()和read()的行为不一样?

发布于 2024-11-27 03:46:30 字数 1157 浏览 1 评论 0原文

我使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

孤凫 2024-12-04 03:46:30

因为 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 of EINVAL or similar.

╭ゆ眷念 2024-12-04 03:46:30

查看手册页:
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);

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文