Sockets 使用sendmsg、recvmsg的优点是什么
我正在学习Linux网络编程,并了解一些有关从套接字读取和写入数据的函数。recv,send,recvmsg,sendmesg。据我所知,recvmsg可以用来传递文件描述符,为套接字的读写增加超时。您能告诉我使用recvmsg、sendmsg比recv、send有什么优势吗?Sockets 使用sendmsg、recvmsg的优点是什么,sockets,Sockets,我正在学习Linux网络编程,并了解一些有关从套接字读取和写入数据的函数。recv,send,recvmsg,sendmesg。据我所知,recvmsg可以用来传递文件描述符,为套接字的读写增加超时。您能告诉我使用recvmsg、sendmsg比recv、send有什么优势吗? 非常感谢。recvmsg和sendmsg可以做以下几件事: 您可以执行分散/聚集缓冲区。例如,let's day您希望接收正好1MB的数据,但每个100KB只有10个缓冲区,然后您可以在单个recvmsg调用中填充每个缓
非常感谢。recvmsg和sendmsg可以做以下几件事:
旧问题,但recvmsg的另一个有用特性是用于在数据包中使用头/数据格式的协议。您可以设置一个用于接收标头的缓冲区,以及另一个用于接收数据的缓冲区 到目前为止,后者只需要根据接收到的数据进行移位,就可以获得连续的数据,而无需任何(额外)内存拷贝。效率更高 想象一下,您需要将一个非常大的文件分部分传输。对于经典recv调用,您需要创建如下缓冲区(伪代码):
while(收到
使用recvmsg,您可以跳过每个数据包的内存拷贝和许多系统调用:
char * file = mmap(...); // Get a writable buffer for this file
while(received < expectedFileSize)
{
char header[sizeof(Header)];
struct iovec v[2] = { { header, sizeof(Header) }, { file + received, expectedFileSize - received } };
msghdr msg = { NULL, 0, v, 2, 0, 0, 0 };
int s = recvmsg(fd, &msg, 0); // Only one syscall here
received += s - sizeof(Header);
}
char*file=mmap(…);//获取此文件的可写缓冲区
while(接收<预期文件大小)
{
字符头[sizeof(头)];
struct iovec v[2]={{header,sizeof(header)},{file+received,expectedFileSize-received};
msghdr msg={NULL,0,v,2,0,0,0};
int s=recvmsg(fd,&msg,0);//这里只有一个系统调用
接收+=s-sizeof(报头);
}
不幸的是,这只能用于固定大小的标题
反过来,假设您需要编写一个HTTP服务器
此协议在发送内容之前发送一组标题。使用sendmsg几乎是执行此任务的1:1方式,其中一个线程正在编译头,而另一个线程正在编译内容
在这种情况下,不需要添加锁定,因为每个线程都在其自己的缓冲区上执行,和内容编译的处理不需要等待标题被完全编译(因为如果没有sendmsg
,您将需要标题大小来将内容附加到标题之后)
char * file = mmap(...); // Get a writable buffer for this file
while(received < expectedFileSize)
{
char header[sizeof(Header)];
struct iovec v[2] = { { header, sizeof(Header) }, { file + received, expectedFileSize - received } };
msghdr msg = { NULL, 0, v, 2, 0, 0, 0 };
int s = recvmsg(fd, &msg, 0); // Only one syscall here
received += s - sizeof(Header);
}