1. 程式人生 > >網絡編程之基於UDP協議套接字

網絡編程之基於UDP協議套接字

本質 系統內存 現象 服務 自身 png 收發消息 accept color

1.UDP協議介紹(數據報協議)

  UDP協議不同於TCP,通信時,它不需要事先建立雙向鏈接,並且不區分客戶端先啟動還是服務端前起,工作原理:基於udp協議傳輸的信息,協議會將數據自動加上自定義的報頭,這樣每一個數據都是一個數據報,而流失協議由於自身優化算法,產生粘包現象,udp不會產生粘包現象,並且發出的消息可以為空,因為就算你發的是空消息,協議也會給你的空消息加上一段自定義報頭,所以它還是一個數據報,而tcp協議在這裏則不能發空消息,一旦發空消息,接收方會一直處於收的狀態,發送方發完空後會一直處於收的狀態,所以對於tcp協議需要加上一些異常處理代碼,防止異常的發生,

  為什麽說udp協議是不可靠而tcp是可靠的呢?這裏面試可能會被問到,答案沒你想得那麽簡單(因為tcp是基於雙向鏈接而udp沒有基於鏈接,數據發出去就行了~~~這麽回答估計你這次面試也就GG了,背後的真正的原理:):首先必須搞清楚一個大的原理,應用程序收發消息都是跟誰打交道的???——沒錯是應用程序自身所在的操作系統,知道這一點之後,再來說,為什麽tcp協議可靠,原因在於服務端向客戶端發出數據(這裏的數據也是先流到服務端的操作系統內存由服務端操作系統向客戶端發)後,客戶端必須向服務端發出確認消息,而服務端發出的數據,操作系統不會立即將內存中的數據立馬清除,而是會等到確認消息後,才會清理數據內存,這個時候的數據才是無用的,如果沒有收到確認信息,服務端隔斷時間會再向客戶端發送內存裏存好的數據,這才是tcp協議通信的可靠的本質,

  反觀udp則比較隨性了,發送端將數據寫好點擊發送後,數據會被加上自定義報頭然後由操作系統發出,發出後立馬清除數據內存,要想用udp有效的傳輸數據,最大數據傳輸範圍應該控制在512bytes,數據量超過這個限制,就無法再保證數據傳輸的穩定性了。

2.tcp協議完整代碼邏輯

技術分享圖片
import socket

client=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client.connect((127.0.0.1,8080))

while True:
    msg=input(>>>: ).strip()
    
if not msg:continue client.send(msg.encode(utf-8)) data=client.recv(1024) print(data.decode(utf-8)) client.close()
客戶端 技術分享圖片
import socket

server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.bind((127.0.0.1,8080))
server.listen(5)

while True:
    conn,client_addr=server.accept()
    print(client_addr)

    
while True: try: data=conn.recv(1024) if not data:break # 針對linux系統 conn.send(data.upper()) except ConnectionResetError: break conn.close() server.close()
服務端

3.udp協議代碼

客戶端:

import socket

client=socket.socket(socket.AF_INET,socket.SOCK_DGRAM) # 數據報協議

while True:
    msg=input(>>>: ).strip()
    client.sendto(msg.encode(utf-8),(127.0.0.1,8080))
    res,server_addr=client.recvfrom(1024)
    print(res.decode(utf-8))

服務端:

import socket

server=socket.socket(socket.AF_INET,socket.SOCK_DGRAM) # 數據報協議
server.bind((127.0.0.1,8080))

while True:
    client_data,client_addr=server.recvfrom(1024)
    msg=input(回復%s:%s>>>: %(client_addr[0],client_addr[1]))
    server.sendto(msg.encode(utf-8),client_addr)

4.基於udp寫實現網絡溝通交流(建議版本qq)

import socket
server=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
server.bind((127.0.0.1,8808))

while True:
    data,client_addr=server.recvfrom(1024)
    print(get a message form %s:%s>>:%s%(client_addr[0],client_addr[1],data.decode(utf-8)))
    msg=input(please recall>>:).strip()
    server.sendto(msg.encode(utf-8),client_addr)
import socket
client=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

while True:
    msg=input(what are you want to talk>>:).strip()
    if not msg:continue
    client.sendto(msg.encode(utf-8),(127.0.0.1,8808))
    msg,addr=client.recvfrom(1024)
    print(get a message from %s:%s>>:%s%(addr[0],addr[1],msg.decode(utf-8)))

技術分享圖片

技術分享圖片

5.基於udp協議編寫時間服務器(訪問就給你放回當前時間)

服務端

import socket,time
server=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
server.bind((127.0.0.1,8808))

while True:
    data,client_addr=server.recvfrom(1024)
    if not data:
        time_list=time.strftime(%Y-%m-%d %X)
    else:
        time_list=time.strftime(data.decode(utf-8))
    server.sendto(time_list.encode(utf-8),client_addr)

訪問端

import socket
client=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

while True:
    msg=input(please input the format of time which are you want get>>:).strip()
    client.sendto(msg.encode(utf-8),(127.0.0.1,8808))
    data,addr=client.recvfrom(1024)
    print(time>>:%s%data.decode(utf-8))

網絡編程之基於UDP協議套接字