应表会传网数物:
应用层、表示层、会话层 (这三层又可以合并为应用层,这样就是五层网络协议【osi五层协议】) python ‘你好‘.encoding(‘utf-8‘)
传输层、 预备如何传输、使用的端口 (port,tcp,udp) 四层路由器,四层交换机
网络层、 ip (ipv4 ipv6) 路由器,三层交换机
数据链路层、 mac (mac, arp协议:可以通过ip找到mac) 二层交换机,网卡(单播、广播、组播,arp用到单播和广播)
物理层 转成电信号
tcp需要先建立连接,然后才能够通信(类似于打电话)
udp不需要建立连接,就可以通信(类似于发信息)
‘‘‘
------------------------------
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)
只出现在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]))
原文:https://www.cnblogs.com/tensorzhang/p/14898523.html