交换机、路由器、服务器组网
1. 通信过程(pc+switch+router+server)
较为复杂的通信过程如:访问 www.baidu.com
注意:一定要配置
- PC:IP、NETMASK、DFGATEWAY、DNS
- ROUTER:IP、NETMASK、路由表
总结
- DNS服务器用来解析出IP(类似电话簿)
- DFGATEWAY(默认网关)用来对顶,当发送的数据包的目的ip不是当前网络时,此数据包包转发的目的ip
- 在路由器中路由表指定数据包的”下一跳”的地址
tcp三次握手
tcp四次挥手
tcp十种状态
注意:
- 当一端收到一个FIN,内核让read返回0来通知应用层另一端已经终止了向本端的数据传送
- 发送FIN通常是应用层对socket进行关闭的结果
tcp的2MSL问题
说明
2MSL即两倍的MSL,TCP的TIME_WAIT状态也称为2MSL等待状态,
当TCP的一端发起主动关闭,在发出最后一个ACK包后,
即第3次握 手完成后发送了第四次握手的ACK包后就进入了TIME_WAIT状态,
必须在此状态上停留两倍的MSL时间,
等待2MSL时间主要目的是怕最后一个 ACK包对方没收到,
那么对方在超时后将重发第三次握手的FIN包,
主动关闭端接到重发的FIN包后可以再发一个ACK应答包。
在TIME_WAIT状态 时两端的端口不能使用,要等到2MSL时间结束才可继续使用。
当连接处于2MSL等待阶段时任何迟到的报文段都将被丢弃。
不过在实际应用中可以通过设置 SO_REUSEADDR选项达到不必等待2MSL时间结束再使用此端口。
tcp长连接和短连接
TCP在真正的读写操作之前,server与client之间必须建立一个连接,
当读写操作完成后,双方不再需要这个连接时它们可以释放这个连接,
连接的建立通过三次握手,释放则需要四次握手,
所以说每个连接的建立都是需要资源消耗和时间消耗的。
TCP通信的整个过程,如下图:
1. TCP短连接
模拟一种TCP短连接的情况:
- client 向 server 发起连接请求
- server 接到请求,双方建立连接
- client 向 server 发送消息
- server 回应 client
- 一次读写完成,此时双方任何一个都可以发起 close 操作
在第 步骤5中,一般都是 client 先发起 close 操作。当然也不排除有特殊的情况。
从上面的描述看,短连接一般只会在 client/server 间传递一次读写操作!
2. TCP长连接
再模拟一种长连接的情况:
- client 向 server 发起连接
- server 接到请求,双方建立连接
- client 向 server 发送消息
- server 回应 client
- 一次读写完成,连接不关闭
- 后续读写操作...
- 长时间操作之后client发起关闭请求
3. TCP长/短连接操作过程
3.1 短连接的操作步骤是:
建立连接——数据传输——关闭连接...建立连接——数据传输——关闭连接
3.2 长连接的操作步骤是:
建立连接——数据传输...(保持连接)...数据传输——关闭连接
4. TCP长/短连接的优点和缺点
-
长连接可以省去较多的TCP建立和关闭的操作,减少浪费,节约时间。
对于频繁请求资源的客户来说,较适用长连接。
-
client与server之间的连接如果一直不关闭的话,会存在一个问题,
随着客户端连接越来越多,server早晚有扛不住的时候,这时候server端需要采取一些策略,
如关闭一些长时间没有读写事件发生的连接,这样可以避免一些恶意连接导致server端服务受损;
如果条件再允许就可以以客户端机器为颗粒度,限制每个客户端的最大长连接数,
这样可以完全避免某个蛋疼的客户端连累后端服务。
- 短连接对于服务器来说管理较为简单,存在的连接都是有用的连接,不需要额外的控制手段。
- 但如果客户请求频繁,将在TCP的建立和关闭操作上浪费时间和带宽。
5. TCP长/短连接的应用场景
-
长连接多用于操作频繁,点对点的通讯,而且连接数不能太多情况。
每个TCP连接都需要三次握手,这需要时间,如果每个操作都是先连接,
再操作的话那么处理速度会降低很多,所以每个操作完后都不断开,
再次处理时直接发送数据包就OK了,不用建立TCP连接。
例如:数据库的连接用长连接,如果用短连接频繁的通信会造成socket错误,
而且频繁的socket 创建也是对资源的浪费。
-
而像WEB网站的http服务一般都用短链接,因为长连接对于服务端来说会耗费一定的资源,
而像WEB网站这么频繁的成千上万甚至上亿客户端的连接用短连接会更省一些资源,
如果用长连接,而且同时有成千上万的用户,如果每个用户都占用一个连接的话,
那可想而知吧。所以并发量大,但每个用户无需频繁操作情况下需用短连好。
listen的队列长度
服务器端运行
#coding=utf-8 from socket import * from time import sleep # 创建socket tcpSerSocket = socket(AF_INET, SOCK_STREAM) # 绑定本地信息 address = ('', 7788) tcpSerSocket.bind(address) connNum = int(raw_input("请输入要最大的链接数:")) # 使用socket创建的套接字默认的属性是主动的,使用listen将其变为被动的,这样就可以接收别人的链接了 tcpSerSocket.listen(connNum) while True: # 如果有新的客户端来链接服务器,那么就产生一个新的套接字专门为这个客户端服务器 newSocket, clientAddr = tcpSerSocket.accept() print clientAddr sleep(1)
客户端运行
#coding=utf-8 from socket import * connNum = raw_input("请输入要链接服务器的次数:") for i in range(int(connNum)): s = socket(AF_INET, SOCK_STREAM) s.connect(("192.168.1.102", 7788)) print(i)
总结
- listen中的black表示已经建立链接和半链接的总数
- 如果当前已建立链接数和半链接数以达到设定值,那么新客户端就不会connect成功,而是等待服务器
手动配置ip
1. 设置IP和掩码
ifconfig eth0 192.168.5.40 netmask 255.255.255.0
2. 设置网关
route add default gw 192.168.5.1