目录
1,七层网络协议
2,TCP/UDP
3,例子4,粘包
1,七层网络协议
应表会传网数物:
应用层、表示层、会话层: (这三层又可以合并为应用层,这样就是五层网络协议【osi五层协议】) python \’你好\’.encoding(\’utf-8\’)
传输层: 预备如何传输、使用的端口 (port,tcp,udp); 四层路由器、四层交换机
网络层: ip(ipv4 ipv6); 路由器、三层交换机
数据链路层: mac(mac, arp协议:可以通过ip找到mac); 二层交换机、网卡(单播、广播、组播,arp用到单播和广播)
物理层 : 转成电信号
2,TCP/UDP
tcp需要先建立连接,然后才能够通信(类似于打电话)
占用连接,可靠(消息不会丢失),实时性高,慢(效率低、面向连接、可靠、全双工)
三次握手
客户端向服务器端发送syn请求
服务端回复ack并发送syn请求
客户端接收到请求后再回复ack,连接建立
在socket中是由 客户端connect() 和 服务端accept()两个命令完成的
四次挥手
客户端向服务端发送fin请求
服务端回复ack确认
服务端向客户端发送fin请求
客户端回复ack确认
在socket中是由 客户端sk.close() 和 服务端 conn.close()两个命令完成的
挥手时服务端的ack和fin不能同时发送,因为客户端发送完所有信息时,服务端不一定完成了所有信息的发送
udp不需要建立连接,就可以通信(类似于发信息)
不占用连接,不够可靠(消息因为网络不稳定可能丢失),实时性不高(效率高、无连接的、不可靠的)
3,例子
\'\'\' ------------------------------ TCP协议 ------------------------------ \'\'\' \'\'\'server\'\'\' import socket sk = socket.socket() sk.bind((\'127.0.0.1\', 6000)) sk.listen() conn, addr = sk.accept() conn.send(\'你好\'.encode(\'utf-8\')) msg = conn.recv(1024) print(msg.decode(\'utf-8\')) conn.close() sk.close() \'\'\'client\'\'\' import socket sk = socket.socket() sk.connect((\'127.0.0.1\', 6000)) msg = sk.recv(1024) print(msg.decode(\'utf-8\')) sk.send(\'再见\'.encode(\'utf-8\')) sk.close() \'\'\' ------------------------------ UDP协议 ------------------------------ \'\'\' \'\'\'server\'\'\' import socket sk = socket.socket(type=socket.SOCK_DGRAM) #SOCK_DGRAM udp default tcp sk.bind((\'127.0.0.1\', 6000)) # msg = sk.recv(1024) # print(msg.decode(\'utf-8\')) while True: msg = sk.recvfrom(1024) print(msg) print(msg[0].decode(\'utf-8\')) if msg[0].decode(\'utf-8\') == \'对方和你断开了连接\': continue msgSend = input(\'>>>\') sk.sendto(msgSend.encode(\'utf-8\'), msg[1]) \'\'\'client\'\'\' import socket sk = socket.socket(type=socket.SOCK_DGRAM) server = (\'127.0.0.1\', 6000) while True: msgSend = input(\'>>>\') if msgSend.upper() == \'Q\': sk.sendto(\'对方和你断开了连接\'.encode(\'utf-8\'), server) break sk.sendto(msgSend.encode(\'utf-8\'), server) msg = sk.recv(1024).decode(\'utf-8\') if msg.upper() == \'Q\': print(\'对方和你断开了连接\') break print(msg)
4,粘包
只出现在tcp协议中,因为tcp协议中多条消息之间没有边界,并且还有各种优化算法,因此会导致发送端和接收端都存在粘包现象:
发送端:两条消息很短,而且发送的间隔时间也很短
接收端:多条消息没有及时接收,而在接收方的缓存堆在一起导致粘包
\'\'\'server\'\'\' import socket sk = socket.socket() sk.bind((\'127.0.0.1\', 6000)) sk.listen() conn, addr = sk.accept() conn.send(b\'hello\') conn.send(b\'byebye\') conn.close() sk.close() \'\'\'client\'\'\' import time import socket sk = socket.socket() sk.connect((\'127.0.0.1\', 6000)) time.sleep(0.1) msg = sk.recv(5) print(msg) msg = sk.recv(4) print(msg) sk.close()
解决粘包问题的本质:设置边界(发送长度、发送消息,交替进行)
1,自定义协议
\'\'\'server\'\'\' import socket sk = socket.socket() sk.bind((\'127.0.0.1\', 6000)) sk.listen() conn, addr = sk.accept() msg1 = input(\'>>>\').encode(\'utf-8\') msg2 = input(\'>>>\').encode(\'utf-8\') def sendFunc(msg): num = str(len(msg)) ret = num.zfill(4) conn.send(ret.encode(\'utf-8\')) conn.send(msg) sendFunc(msg1) sendFunc(msg2) conn.close() sk.close() \'\'\'client\'\'\' import socket sk = socket.socket() sk.connect((\'127.0.0.1\', 6000)) def receiveFunc(): num = sk.recv(4).decode(\'utf-8\') msg = sk.recv(int(num)) print(msg.decode(\'utf-8\')) receiveFunc() receiveFunc() sk.close()
2,struct模块
import struct \'\'\'~2**32, 排除符号位,相当于1G的数据的长度\'\'\' num1 = 1231341234 num2 = 1342342 num3 = 12 ret1 = struct.pack(\'i\', num1) print(ret1) print(len(ret1)) ret2 = struct.pack(\'i\', num2) print(ret2) print(len(ret2)) ret3 = struct.pack(\'i\', num3) print(ret3) print(len(ret3)) ret11 = struct.unpack(\'i\', ret1) print(ret11) print(type(ret11[0]))
以上就是python 网络编程要点总结的详细内容,更多关于python 网络编程的资料请关注免费资源网其它相关文章!
暂无评论内容