一、基于UDP協定通信的套接字
udp是沒有連結的,是以先啟動哪一端都不會報錯

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

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無連接配接,是以可以同時多個用戶端去跟服務端通信(實作簡單的并發,并不可靠)

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協定通信

# 服務端必須滿足至少三點:
# 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() # 連結循環

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

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協定通信

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()

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)

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)
焚膏油以繼晷,恒兀兀以窮年。