8-2udp和tcp網絡編程以及粘包和解決粘包的方法

一  tcp網絡編程編程

 1 server 端
 2 
 3 import socket
 4 sk=socket.socket()  #實例化一個對象
 5 sk.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)#端口能夠重用
 6 sk.bind(('127.0.0.1',9100))
 7 sk.listen()#監聽
 8 while True:
 9     conn,addr=sk.accept() #阻塞,三次握手完畢
10     while True:
11         inp=input('請輸入你要發送的消息:')
12         conn.send(inp.encode('utf-8'))
13         if inp == 'q': break
14         ret=conn.recv(1024).decode('utf-8')
15         if ret == 'q': break
16         print(ret)
17 
18     conn.close()
19 sk.close()
  client端
1
import socket 2 sk=socket.socket() 3 #while True: 4 sk.connect(('127.0.0.1',9100)) 5 while True: 6 ret=(sk.recv(1024).decode('utf-8')) 7 if ret == 'q': break 8 print(ret) 9 inp=input('請輸入你要發送的消息:') 10 sk.send(inp.encode('utf-8')) 11 if inp == 'q': break 12 13 sk.close()

二 tcp粘包緩存

1  發送方的緩存機制網絡

發送數據時間間隔很短,數據了很小,會合到一塊兒,產生粘包socket

 1 服務端
 2 #_*_coding:utf-8_*_
 3 from socket import *
 4 ip_port=('127.0.0.1',8080)
 5 
 6 tcp_socket_server=socket(AF_INET,SOCK_STREAM)
 7 tcp_socket_server.bind(ip_port)
 8 tcp_socket_server.listen(5)
 9 
10 
11 conn,addr=tcp_socket_server.accept()
12 
13 
14 data1=conn.recv(10)
15 data2=conn.recv(10)
16 
17 print('----->',data1.decode('utf-8'))
18 print('----->',data2.decode('utf-8'))
19 
20 conn.close()
21 
22 服務端
服務端
 1 #_*_coding:utf-8_*_
 2 import socket
 3 BUFSIZE=1024
 4 ip_port=('127.0.0.1',8080)
 5 
 6 s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
 7 res=s.connect_ex(ip_port)
 8 
 9 
10 s.send('hello'.encode('utf-8'))
11 s.send('egg'.encode('utf-8'))
客戶端

 

2接收方的緩存機制tcp

客戶端發送了一段數據,服務端只收了一小部分,服務端下次再收的時候仍是從緩衝區拿上次遺留的數據,產生粘包) ide

 1 #_*_coding:utf-8_*_
 2 from socket import *
 3 ip_port=('127.0.0.1',8080)
 4 
 5 tcp_socket_server=socket(AF_INET,SOCK_STREAM)
 6 tcp_socket_server.bind(ip_port)
 7 tcp_socket_server.listen(5)
 8 
 9 
10 conn,addr=tcp_socket_server.accept()
11 
12 
13 data1=conn.recv(2) #一次沒有收完整
14 data2=conn.recv(10)#下次收的時候,會先取舊的數據,而後取新的
15 
16 print('----->',data1.decode('utf-8'))
17 print('----->',data2.decode('utf-8'))
18 
19 conn.close()
服務端
 1 #_*_coding:utf-8_*_
 2 import socket
 3 BUFSIZE=1024
 4 ip_port=('127.0.0.1',8080)
 5 
 6 s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
 7 res=s.connect_ex(ip_port)
 8 
 9 
10 s.send('hello egg'.encode('utf-8'))
客戶端

三 解決粘包問題spa

 1 import socket
 2 import struct
 3 sk=socket.socket()
 4 sk.bind(('127.0.0.1',8090))
 5 sk.listen()
 6 conn,addr=sk.accept()
 7 inp=input('>>>:').encode('utf-8')
 8 inp_len=len(inp)#計算用戶輸入的長度
 9 bytes_msg=struct.pack('i',inp_len)#將數字轉換成固定的bytes
10 conn.send(bytes_msg) #先發送報頭的長度4個bytes
11 conn.send(inp)#在發送報頭的字節格式
12 conn.send(b'alex sb')#最後發送真實內容的字節格式
13 conn.close()
14 sk.close()
服務端
 1 import socket
 2 import struct
 3 sk=socket.socket()
 4 sk.connect(('127.0.0.1',8090))
 5 num=sk.recv(4) #先接受bytes的長度
 6 num=struct.unpack('i',num)[0]#提取報文的長度
 7 print(sk.recv(num).decode('utf-8'))
 8 print(sk.recv(10))
 9 
10 sk.close()
客戶端

 

 

四 udpcode

 1 udp server端
 2 
 3 import socket
 4 sk=socket.socket(type=socket.SOCK_DGRAM)
 5 sk.bind(('127.0.0.1',8899))
 6 while True:
 7     msg,addr=sk.recvfrom(1024)
 8     print(msg.decode('utf-8'),addr)
 9     inp=input('>>>:')
10     if inp=='q':break
11     sk.sendto(inp.encode('utf-8'),addr)
12     #print(msg)
13 sk.close()
 1 udp client
 2 
 3 import socket
 4 sk=socket.socket(type=socket.SOCK_DGRAM)
 5 sk.bind(('127.0.0.1',8899))
 6 while True:
 7     msg,addr=sk.recvfrom(1024)
 8     print(msg.decode('utf-8'),addr)
 9     inp=input('>>>:')
10     if inp=='q':break
11     sk.sendto(inp.encode('utf-8'),addr)
12     #print(msg)
13 sk.close()
相關文章
相關標籤/搜索