本文主讲tcp和tcp的抽象socket。 由于tcp过于复杂,你可以把本文当作专栏看。本文的问题和回答是本人那时的突发奇想和所思所想,不代表此时。可能那时会错误,此时也不对。问题会伴随着本人的需要而提出,回答会随着本人的认知而更新。
1.tcp连接是怎么发送
端:指端口
------这个问题主要是因为已经习惯了A端和B端发送数据是在tcp连接之后,那在tcp建立连接之前,tcp连接又是谁发送。这个问题关键在于把tcp连接看成数据,则tcp连接是怎么发送的。已知 两端之间不论谁向谁建立连接必须要先发一个SYN包。如A端向B端建立连接则A端要先发送一个SYN包。则问题等价于第一个SYN包是怎么发送的。那么,这个问题成立的前提是A有A端,B有B端,也就是AB两端先安装TCP。接着A端向B端发送SYN包。问题好像一下字明了了。SYN包由IP发送。这应该是问题答案。展开下答案:AIP向B发送数据。BIP收到数据后再按TCP解析,此时数据成为SYN包。成功发送。但有个衍生问题,就是这个问题成立的前提是不是只要B有B端就可以。
衍生问题
------因为从答案的流程来看似乎不需要A支持TCP,A的IP只要能向BIP发送数据就行了。经过我的深思熟虑,觉得就是这样的,即便是以A有数据链路层,B有IP层为例也是如此。因为可以把A和B网线连接在一起就能发送了。此时B有IP,A无IP。我们假设人类有收发器可以收发数据。如图
那么,A是可以向B发送数据的,B再经大脑解析。B也可以向A发送数据,但A无法解析数据。
2.关于tcp连接缓冲区大小
查看缓冲区默认大小
------有两种方法 ------第一种 查看文件 cat /proc/sys/net/ipv4/tcp_rmem //接收缓冲区 4096 87380 6291456
cat /proc/sys/net/ipv4/tcp_wmem //发送缓冲区 4096 16384 4194304 //第一个最小值,第二个默认值,第三个最大值。 ------第二种 getsockopt
#include<sys/socket.h>
int sock_server = socket(AF_INET, SOCK_STREAM, 0);
int val;
socklen_t valLen = sizeof(int);
getsockopt(sock_server, SOL_SOCKET, SO_RCVBUF, &val, &valLen);
cout << "套接字接收默认大小 :" << val<< endl;
getsockopt(sock_server, SOL_SOCKET, SO_SNDBUF, &val, &valLen);
cout << "套接字发送默认大小 :" << val<< endl;
修改缓冲区大小
------第二种 setsockopt 修改规则: 1.当要修改的值val <= 1/2最小值,则设置成最小值 2.当1/2最小值 < val <= 1/2最大值,则设置2val 3.当val > 1/2最大值,则设置最大值。 直观总结:即不论val多小,也会返回最小;不论val多大,也不会超过最大。其余返回2val。
val = 1;
setsockopt(sock_server, SOL_SOCKET, SO_RCVBUF, &val, sizeof(int));
getsockopt(sock_server, SOL_SOCKET, SO_RCVBUF, &val, &valLen);
cout << "套接字接收大小 :" << val << endl;
val = 1;
setsockopt(sock_server, SOL_SOCKET, SO_SNDBUF, &val, sizeof(int));
getsockopt(sock_server, SOL_SOCKET, SO_SNDBUF, &val, &valLen);
cout << "套接字发送大小 :" << val << endl;
查看修改最大值
------查看最大值 cat /proc/sys/net/core/rmem_max //接收 212992 cat /proc/sys/net/core/wmem_max //发送 212992 此值仅是最大值的1/2,也就是最大值为425984。 1/2的意义在于应用程序中的val值不能超过212992,否则没有意义。
------修改最大值 sudo sysctl -w net.core.rmem_max=1048576(1M) 结合上面 也就是最大值为2M,而这个1M的意义在于程序中的变量不应该超过这个值。
衍生问题
------我们会发现 cat /proc/sys/net/ipv4/tcp_rmem 和 cat /proc/sys/net/core/rmem_max 显示的接收最大值相差甚远 4096 87380 6291456?????? 212992 其实
3.为什么需要监听套接字
|