天天看點

python-基于UDP通信的套接字,socketserver子產品的使用

一、基于UDP協定通信的套接字

udp是沒有連結的,是以先啟動哪一端都不會報錯

python-基于UDP通信的套接字,socketserver子產品的使用
python-基于UDP通信的套接字,socketserver子產品的使用
import socket

server=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
server.bind(('127.0.0.1',8082))

while True:
    data,client_addr=server.recvfrom(1024)
    print(data)
    server.sendto(data.upper(),client_addr)

server.close()      

server

python-基于UDP通信的套接字,socketserver子產品的使用
python-基于UDP通信的套接字,socketserver子產品的使用
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',8082))
    data,server_addr=client.recvfrom(1024)
    print(data)      

client

由于udp無連接配接,是以可以同時多個用戶端去跟服務端通信(實作簡單的并發,并不可靠)

python-基于UDP通信的套接字,socketserver子產品的使用
python-基于UDP通信的套接字,socketserver子產品的使用
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',8082))
    data,server_addr=client.recvfrom(1024)
    print(data)      

client2

udp不會出現粘包現象,因為每個中就已經有了報頭,這樣對于接收端來說,容易區分處理。

udp的recvfrom是阻塞的,一個recvfrom(x)必須對唯一一個sendinto(y),收完了x個位元組的資料就算完成,若是y>x資料就丢失,這意味着udp根本不會粘包,但是會丢資料,不可靠

二、socketserver子產品

socketserver子產品簡化了編寫網絡服務程式的任務,是python标準庫中很多伺服器架構的基礎。

socketserver中包含了兩種類,一種為服務類(server class),一種為請求處理類(request handle class),前者主要做的是建立連結的過程,後者注重使用者資料的處理

要實作一項服務,還必須派生一個handler class請求處理類,并重寫父類的handle()方法。handle方法就是用來專門是處理請求的。該子產品是通過服務類和請求處理類組合來處理請求的。SocketServer子產品提供的請求處理類有BaseRequestHandler。

1.基于tcp協定通信

python-基于UDP通信的套接字,socketserver子產品的使用
python-基于UDP通信的套接字,socketserver子產品的使用
# 服務端必須滿足至少三點:
# 1. 綁定一個固定的ip和port
# 2. 一直對外提供服務,穩定運作
# 3. 能夠支援并發
import socketserver

# 自定義類用來處理通信循環
class MyTCPhanler(socketserver.BaseRequestHandler):
    def handle(self):
        while True:
            try:
                data = self.request.recv(1024)
                if len(data) == 0: break  # 針對linux系統
                print('-->收到用戶端的消息: ', data)
                self.request.send(data.upper())
            except ConnectionResetError:
                break

        self.request.close()


if __name__ == '__main__':
    server=socketserver.ThreadingTCPServer(('127.0.0.1',8081),MyTCPhanler)
    server.serve_forever() # 連結循環      
python-基于UDP通信的套接字,socketserver子產品的使用
python-基于UDP通信的套接字,socketserver子產品的使用
from socket import *

client = socket(AF_INET, SOCK_STREAM)
client.connect(('127.0.0.1', 8081))

# 通信循環
while True:
    # msg=input('>>: ').strip() #msg=''
    # if len(msg) == 0:continue
    # client.send(msg.encode('utf-8')) #client.send(b'')
    client.send('hello'.encode('utf-8')) #client.send(b'')
    # print('has send')
    data=client.recv(1024)
    # print('has recv')
    print(data)

client.close()      

client1

python-基于UDP通信的套接字,socketserver子產品的使用
python-基于UDP通信的套接字,socketserver子產品的使用
from socket import *

client = socket(AF_INET, SOCK_STREAM)
client.connect(('127.0.0.1', 8081))

# 通信循環
while True:
    # msg=input('>>: ').strip() #msg=''
    # if len(msg) == 0:continue
    # client.send(msg.encode('utf-8')) #client.send(b'')
    client.send('hello'.encode('utf-8')) #client.send(b'')
    # print('has send')
    data=client.recv(1024)
    # print('has recv')
    print(data)

client.close()      

2.基于udp協定通信

python-基于UDP通信的套接字,socketserver子產品的使用
python-基于UDP通信的套接字,socketserver子產品的使用
import socketserver

class MyUdphandler(socketserver.BaseRequestHandler):
    def handle(self):
        data,sock=self.request
        sock.sendto(data.upper(),self.client_address)

if __name__ == '__main__':
    server=socketserver.ThreadingUDPServer(('127.0.0.1',8081),MyUdphandler)
    server.serve_forever()      
python-基于UDP通信的套接字,socketserver子產品的使用
python-基于UDP通信的套接字,socketserver子產品的使用
from socket import *

client=socket(AF_INET,SOCK_DGRAM)

while True:
    client.sendto(b'hello',('127.0.0.1',8081))
    data,server_addr=client.recvfrom(1024)
    print(data)      
python-基于UDP通信的套接字,socketserver子產品的使用
python-基于UDP通信的套接字,socketserver子產品的使用
from socket import *

client=socket(AF_INET,SOCK_DGRAM)

while True:
    client.sendto(b'hello',('127.0.0.1',8081))
    data,server_addr=client.recvfrom(1024)
    print(data)      

焚膏油以繼晷,恒兀兀以窮年。