背景:做測試工作時,經常碰到只做上游,或只做下游項目的情況。此時需要自己寫腳本模擬另一端的數據。本文在此記錄如何實現一個簡單的socket通信。
client.py
# 導入socket庫
import socket
import threading
import time
HOST = '127.0.0.1'
POST = 50009
def loop():
# 創建一個socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # AF_INET指定使用IPv4協議,SOCK_STREAM指定使用面向流的TCP協議
# 建立連接:
s.connect((HOST, POST)) # 服務器的IP地址和端口號
n = 0
while n < 10:
n = n + 1
data_heartbeat = b'$000001#'
# 發送數據
s.sendall(data_heartbeat)
time.sleep(1)
# 打印接收服務端的數據
print(s.recv(1024).decode("gbk"))# 每次最多接收1k字節,編碼是gbk
for i in range(3):
t= threading.Thread(target=loop, name='LoopThread').start()
server.py
import socketserver
import time
class Handler(socketserver.BaseRequestHandler):
def setup(self):
"""連接成功,塞入連接池"""
self.request.sendall("connect success!".encode(encoding='gbk')) # 向客戶端發送連接成功信息
print("Connected by ", self.client_address)
socket_request_pool.append(self.request) # 當前socket連接對象放入連接池
def handle(self):
""" 收到消息處理,異常或空消息,斷開連接,心跳則返回消息"""
try:
while True:
self.data = self.request.recv(1024)
print("online num", len(socket_request_pool))
print("{} send:".format(self.client_address), self.data.decode(encoding="gbk"))
if not self.data:
print("Connection lost")
self.remove()
break
self.data_str = self.data.decode('GBK') # 接收到的數據從byte-->str ,gbk編碼
self.data_content = self.data_str.strip('$#') # 去掉首尾字符
if len(self.data_content) == 6:
self.request.sendall(self.data) # 發送收到的內容,即心跳協議的響應
time.sleep(2)
print("服務端發送心跳響應成功," + '終端號:' + self.data_content + ',' + time.strftime("%Y-%m-%d %H:%M:%S",
time.localtime()))
except Exception as e:
print(self.client_address, "Connection lost")
self.remove()
finally:
self.request.close()
def finish(self):
""" 環境清理,在handle()之后執行清除操作,默認什么都不做,
如果setup()和handle()方法都不生成異常,則無需調用該方法"""
print("client clean", self.client_address)
def remove(self):
"""連接斷開后,從連接池中刪除socket對象"""
print("client remove")
socket_request_pool.remove(self.request)
print("online num: ", len(socket_request_pool))
if __name__ == '__main__':
ADDRESS = ('127.0.0.1', 50009)
socket_request_pool = [] # 連接池
server = socketserver.ThreadingTCPServer(ADDRESS, Handler)
server.serve_forever()