- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我使用linux 3.x
和现代glibc(2.19)
。
我想发送几个以太网帧,而无需从内核/用户空间来回切换。
我有MTU = 1500
,我想发送800 KB
。
我这样初始化接收者地址:
struct sockaddr_ll socket_address;
socket_address.sll_ifindex = if_idx.ifr_ifindex;
socket_address.sll_halen = ETH_ALEN;
socket_address.sll_addr[0] = MY_DEST_MAC0;
//...
sendto/sendmsg 800KB / 1500 ~= 500
次,并且一切正常,但这需要用户空间
<->
内核协商〜每秒
500 * 25
次。我要避免它。
init struct msghdr::msg_iov
,
msghdr::msg_iov
无法用
size > MTU
描述某些内容。
(800KB)
,并将其读取到内存中。因此,
struct iovec
对我很有用,我可以创建适当数量的以太网头,并且必须
iovec per 1500 packet
,一分指向数据,一分指向以太网 header 。
最佳答案
哇
我的上一家公司制造了实时Hidef视频编码硬件。在实验室中,我们必须通过绑定(bind)链接以每秒200MB的速度传输数据,因此我对此有一些经验。以此为基础。
在调整之前,您必须先进行测量。您不想执行多个系统调用,但是可以通过计时测量证明开销很大吗?
我在clock_gettime
周围使用了一个包装例程,该例程以纳秒级精度返回一天中的时间(例如(tv_sec * 100000000) + tv_nsec
)。称此为“nanotime”。
因此,对于任何给定的系统调用,您都需要进行以下测量:
tstart = nanotime();
syscall();
tdif = nanotime() - tstart;
send/sendto/sendmsg/write
,这样做会减少数据量,因此您可以确定自己没有阻塞[或使用O_NONBLOCK(如果适用)]。这给您系统调用的开销
write
调用怎么样?一个用于标题,一个用于数据[全部800KB]。
write
可以在套接字上使用,没有
EMSGSIZE
错误或限制。
datamax = 800 * 1024; // or whatever
buflen = sizeof(struct header) + datamax;
buf = malloc(buflen);
while (1) {
datalen = read(fdfile,&buf[sizeof(struct header)],datamax);
// fill in header ...
write(fdsock,buf,sizeof(struct header) + datalen);
}
setsockopt
来增加套接字的内核缓冲区的大小。否则,您可以发送数据,但是在接收者将其耗尽之前,它将被丢弃到内核中。在下面的更多内容。
u64 send_departure_time; // set by sender from nanotime
u64 recv_arrival_time; // set by receiver when the packet arrives
Xs
。接收器在到达时对其进行标记。接收方立即向发送方发回一条消息,称为发送方
Xr
,带有离开戳和
Xs
的内容。当发件人收到此邮件时,它将在到达时间上加盖戳记。
T1 -- time packet Xs departed sender
T2 -- time packet Xs arrived at receiver
T3 -- time packet Xr departed receiver
T4 -- time packet Xr arrived at sender
ifconfig
或使用
ioctl
的
SIOCSIFMTU
调用设置更大的MTU来减少开销。我推荐
ioctl
。您可能不需要将MTU设置为800KB。 CPU的NIC卡有实际限制。您可以轻松地将MTU从1500增加到15000。这将使系统调用开销减少10倍,并且可能“足够好”。
sendto/sendmsg
。这两个
write
调用基于对TCP/UDP的转换。但是,我怀疑带有
sendmsg
的
msg_iov
将比
sendto
拥有更多的开销。如果您进行搜索,则会发现大多数想要使用的示例代码都使用
sendto
。
sendmsg
对您来说似乎减少了开销,但可能会导致内核更多的开销。这是一个使用
sendto
的示例:
http://hacked10bits.blogspot.com/2011/12/sending-raw-ethernet-frames-in-6-easy.html
However, once again, I must say that you must be able to measure your performance before you blindly try to improve it.
read
syscall的影响。不仅来自系统调用开销,而且具有最佳读取长度。例如,IIRC,磁盘到磁盘或文件到文件的复制/传输的最佳传输大小为64KB,具体取决于文件系统或底层磁盘的特性。
关于c++ - sendmsg +原始以太网+几帧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26912561/
我正在尝试在 Linux 中实现自己的传输层协议(protocol)以进行实验。我将使用套接字接口(interface)并使用 sock_register 添加我的协议(protocol)。对于 pr
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 这个问题似乎偏离主题,因为它缺乏足够的信息来诊断问题。 更详细地描述您的问题或 include a mini
我想知道内核如何使用这个 sendmsg() 函数填充 ip header 。 sendmsg() 函数用于在较少的连接中发送消息通过套接字。我们向该函数传递 3 个参数。它们是,文件描述符,msgh
首先是一些上下文:有一个主程序(一个网络服务器),它派生了一堆工作人员,并等待传入的连接。当它接受一个时,它通过 sendmsg() 原语将套接字描述符发送给其中一个工作人员。 这是应该发送描述符
我不是 C 编程专家,但我正在尝试使用 sendmsg() 和 recvmsg() 编写一个相当简单的程序来在客户端和服务器(两者都在同一台机器上,所以基本上我是在向本地主机发送消息)。 在初始化所需
如您所知,sendmsg 有这样的声明: int sendmsg(int s, const struct msghdr *msg, int flags); 和msghdr结构有这种形式: struct
sendmsg() 允许将辅助数据发送到另一个套接字,我想知道它是如何工作的。 1) 辅助数据是否与正常消息一起打包? 2) 如果是这样,远程接收套接字如何知道如何解析它? 3) 远程接收客户端如何检
我正在将项目从 Delphi 2006 升级到 Delphi XE2,并且遇到了编译错误没有可以使用这些参数调用的“SendMsg”的重载版本。这是问题所在的代码。 procedure TMessag
我使用linux 3.x和现代glibc(2.19)。 我想发送几个以太网帧,而无需从内核/用户空间来回切换。 我有MTU = 1500,我想发送800 KB。 我这样初始化接收者地址: struct
我正在使用 unix 域套接字在不同进程之间发送打开的文件描述符。 Unix 域套接字工作正常,但是当我使用 sendmsg 发送文件描述符时,发生了一些奇怪的事情。该函数在 sendmsg 之后返回
我正在编写一个程序,使用 sendmsg 在两个进程之间传递文件描述符和 recvmsg通过域套接字。对于发送文件描述符,附加数据包含在 msghdr.msg_iov 中和 msghdr.msg_io
在 Linux 中运行 ldapsearch 实用程序时,“sendmsg”函数失败并出现错误代码 9。错误代码 9 代表什么?手册页未提供有关错误代码的信息。 最佳答案 您可以在此页面中找到所有错误
在 IPv4 的情况下,我看到 sendmsg 有以下行为: 假设10.1.2.3是客户端IP。10.1.2.10配置在客户端的其中一个接口(interface)上。 在UDP报文中,在数据包中加入如
我正在尝试使用 C 通过 sendmsg 发送原始以太网数据包。此代码成功打开原始数据包套接字,尝试用单个字节数组 (char message[]) 填充 struct iovec,然后用目标地址、地
我拥有的是进程 ID 和来自该进程的文件描述符。除了 sendmsg 之外,还有什么方法可以复制(或重新打开)该进程的文件描述符以供 Linux 中的另一个进程使用? Windows 有用于此目的的
如果为 in_pktinfo.ipi_ifindex 设置了值,则使用 sendmsg() 可以指定从哪个接口(interface)发送数据报。 如果数据包是对使用 recvmsg() 接收到的数据报
我建立了一个简单的客户端和服务器程序,使用 TCP 套接字进行通信。服务器等待客户端连接,并回复是否收到客户端的消息。以下是代码在服务器和客户端中的实现方式: 服务端代码: listen(sockf
我使用 cmsg 在 linux socket tx 上激活时间戳。 ssize_t sendWithOptions (int sd, std::vector &payload, uint32_t d
我在 UDP 套接字编程中遇到了一些问题。我想使用 sendmsg() 和 recvmsg() API 以便能够在客户端和服务器之间进行通信。客户端代码返回错误号 105 {ENOBUFS}。我不知道
我正在编写自己的 DNS 黑洞来阻止我家庭网络上的广告和恶意软件。我意识到这种类型的程序已经存在,但我想学习这个过程并编写自己的程序。从 Linux 文档来看,似乎可以告诉 sendmsg() 使用不
我是一名优秀的程序员,十分优秀!