2013年(6)
分类: LINUX
2013-11-07 16:30:58
问题1:
下面这段代码的,rcvbuf 跟 sendbuf 分贝设置设置多大合适?
sockfd = socket(AF_INET, SOCK_STREAM, 0);
read = recv(sockfd ,rcvbuf,sizeof(rcvbuf), 0);
write = send(sockfd ,sendbuf,sizeof(sendbuf), 0);
解答:
上面的代码是一个正常的tcp socket,两个buf的大小应该是没有大小限制,但是网上说有64k的限制,这一点我没有查阅相关资料,不敢确定。但是,至少有一点是确定的,可以接收或者发送送大于MTU的数据包。
ps:MTU是链路层的概念,在tcp层是mss,但是为了这里讨论方便,将他俩视为"一个概念",就是socket(packet 、raw socket)所能发送的最大字节数,二者的区别,可以去google.
问题2:
下面二者的区别?
raw_socket = socket(AF_INET, SOCK_RAW, IPPROTO_TCP);
packet_socket = socket(PF_PACKET, SOCK_RAW, IPPROTO_TCP);
解答:
第一个是基于AF_INET协议族的raw socket,第二个是基于PF_PACKET的raw socket,都可以用于抓包,但是二者抓包的位置不一样,方式1抓包是在tcp/ip协议层之上,方式2是在
链路层抓到的包,所以造成的结果是方式1抓到的包是经过ip层的分片重组的,所以在没有网卡的一些特性的支持下(嘿嘿,下面会说到网卡的一些特性对抓包的影响),方式1抓到的其实是数据流,方式2抓到的是单个的数据包。所以用方式1抓包的话,接收buf的大小应该是任意的,但是这点没有验证过,理论上是这样。现在用方式1抓包的少了,也懒得去验证了,下面见证奇葩,谈下一个问题。
问题3:
下面这段代码的,rcvbuf 跟 sendbuf 分贝设置设置多大合适?
read = recv(packet_socket,rcvbuf,sizeof(rcvbuf), 0);
write = send(packet_socket ,sendbuf,sizeof(sendbuf), 0);
因为packet socket是在链路层抓包的,所以抓到的包不会经过协议栈,也就不会被分片重组,所以理论上在普通的以太环境中,rcvbuf的大小不能小于1514(MTU + 14的链路层长度),因为如果rcvbuf太小的话,比如rcvbuf大小是1400 ,接收到1500的一个包,多余的100字节会被丢弃掉,就会出问题。
但是,,,
用packet socket确实抓到了大于MTU的包,如何解释?这跟在wireshark中抓包抓到大于MTU的包是一回事,linux wireshark 用的应该也是packet socket。
难道无解???NO!!!!且看下面分解。。
先看下关于网卡的一些特性,秘密就在这: