使用原始套接字發送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