小编Ang*_*gro的帖子

是否有一种可移植的方法可以从类似套接字的文件描述符中丢弃一些可读字节?

是否有一种可移植的方法可以丢弃来自套接字的许多传入字节而不将它们复制到用户空间?在常规文件上,我可以使用lseek(),但在套接字上,这是不可能的。我有两种可能需要它的场景:

  1. 记录流到达文件描述符(可以是 TCP、SOCK_STREAM 类型 UNIX 域套接字或可能是管道)。每个记录前面都有一个固定大小的标头,指定其类型和长度,后面是可变长度的数据。我想先读取标头,如果它不是我感兴趣的类型,我想丢弃以下数据段,而不将它们传输到用户空间到虚拟缓冲区中。

  2. 长度可变且不可预测的记录流到达文件描述符。由于异步性质,当 fd 变得可读时,记录可能仍然不完整,或者当我尝试将固定数量的字节读入缓冲区时,它们可能是完整的,但下一条记录的一部分可能已经存在。我想停止在记录之间的确切边界处读取文件描述符,这样我就不需要管理我不小心从文件描述符中读取的部分加载的记录。因此,我使用recv()withMSG_PEEK标志读入缓冲区,解析记录以确定其完整性和长度,然后再次正确读取(从而实际上从套接字中删除数据)到准确的长度。这将复制数据两次 - 我想通过简单地丢弃套接字中缓冲的确切数量的数据来避免这种情况。

在 Linux 上,我认为可以通过使用splice()数据并将其重定向到/dev/null而不将它们复制到用户空间来实现这一点。但是,splice()仅适用于 Linux,并且sendfile()更多平台上支持的类似功能不能使用套接字作为输入。我的问题是:

  1. 有没有一种可移植的方法来实现这一目标?是否也可以在其他没有 UNIX(主要是 Solaris)的 UNIX 上运行splice()

  2. splice()-ing是/dev/null在 Linux 上执行此操作的有效方法,还是浪费精力?

理想情况下,我希望有一个简单地从内核中的文件描述符fdssize_t discard(int fd, size_t count)中删除可读字节(即不将任何内容复制到用户空间),阻塞可阻止的 fd 直到丢弃请求的字节数,或者返回成功的数量就像在非阻塞 fd 上丢弃字节或 EAGAIN 一样。当然,并在常规文件上推进查找位置:)read()

c unix sockets io zero-copy

6
推荐指数
1
解决办法
1636
查看次数

C /预处理器:检测__builtin功能是否可用

是否有可能以某种方式确定是否存在内部函数,例如__builtin_bswap16编译器提供的函数?优选地,我希望能够仅使用预处理器来确定该功能是否存在.

在我的特定情况下,我__builtin_bswap16在我的代码中使用/ 32/64函数,在编译32位时,它与GCC 4.x一起正常工作.后来我切换到64位Linux,发现它 __builtin_bswap16突然消失了 - 我收到了一个链接器错误:

"未定义引用`__builtin_bswap16'".

我想这与64位模式下某些ASM操作的可用性有关.

稍后我试图在不同的机器上编译这个代码,遗憾的是只安装了旧版本的GCC并且根本不支持这些功能.

我希望这个代码可以在任何地方编译,使用__builtin_bswap函数(如果提供),byteswap如果没有,则回退到手工编写的例程.是否有可能通过预处理器以某种方式实现这一点?

我明显的尝试,例如:

...
#define MYBSWAP16(v) (v>>8)|(v<<8)
#ifdef __builtin_bswap16
printf("bswap16 is defined : %04x\n", __builtin_bswap16(0x1234));
#else
printf("bswap16 is not defined : %04x\n", MYBSWAP16(0x1234) );
#endif
...
Run Code Online (Sandbox Code Playgroud)

没有成功,因为__builtin_bswap16/ 32/64总是被评估为未定义.有没有办法让它在C源代码中自动工作,或者是在Makefile中手动定义常量的唯一方法,例如HAVE_BSWAP并通过-D选项传递它们?

请注意,我的问题不一定具体__builtin_bswap,我正在寻找检测某些功能是否可用的一般方法.

c gcc c-preprocessor

5
推荐指数
1
解决办法
2731
查看次数

标签 统计

c ×2

c-preprocessor ×1

gcc ×1

io ×1

sockets ×1

unix ×1

zero-copy ×1