使用原始套接字发送IP报文,通过setsocketopt中的IP_HDRINCL(Header Include)选项来设置socket,由应用而不是协议栈自动填充IP header。
原来是通过sendto发送,在实际测试中发现每次sendto调用需要10微秒做左右。就像stackoverflow的这篇文章一样,希望通过sendmsg提高发送速度。
struct msghdr {
void *msg_name; /* optional address */
socklen_t msg_namelen; /* size of address */
struct iovec *msg_iov; /* scatter/gather array */
size_t msg_iovlen; /* # elements in msg_iov */
void *msg_control; /* ancillary data, see below */
size_t msg_controllen; /* ancillary data buffer len */
int msg_flags; /* flags (unused) */
};
我们将多个已构造的IP包,填充到msg_iov数组内,再调用sendmsg,结果出错,返回EMSGSIZE,即message too long。
查阅资料后发现,对于不需要协议栈填充IP头的原始套接字,msg_iov数据总长度超过MTU时,sendmsg不能一次发送。
如果没有设置IP_HDRINCL来由我们自己定义IP头部,那么sendmsg会进行IP分片。
综上,sendmsg无法提升原始套接字发送IP包的速度。
参考:
http://blog.csdn.net/liuxingen/article/details/45622517
http://sock-raw.org/papers/sock_raw