Python TCPServer 多線程多客戶端通信的實(shí)現(xiàn)
最簡單、原始的TCP通信demo
服務(wù)端Http請(qǐng)求:
import socket
# 創(chuàng)建一個(gè)servicesocke
serviceSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 給服務(wù)器綁定地址(ip地址,端口號(hào))
serviceSocket.bind(("192.168.171.1", 80))
print("等待客戶端接入")
# sock 是客戶端的socket信息
# addr 是客戶端的地址(ip,端口)
sock, addr = serviceSocket.accept()
print(f"sock from client:{sock}")
print(f"addr of client:{addr}")
while True:
# 接收客戶端的請(qǐng)求
recvData = sock.recv(1024)
print("客戶端說:%s" % (recvData.decode("utf-8")))
sendData = input("服務(wù)器說:")
# 發(fā)送(回復(fù))數(shù)據(jù)給客戶端
sock.send(sendData.encode("utf-8"))
客戶端Http請(qǐng)求:
import socket
# 創(chuàng)建客戶端socket
clientSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 連接服務(wù)器
clientSocket.connect(("192.168.171.1", 80))
while True:
# 發(fā)送消息給服務(wù)器
sendData = input("客戶端說:")
if sendData == "bye":
clientSocket.send(sendData.encode("utf-8")) # 編碼:將數(shù)據(jù)裝換成二進(jìn)制形式
break
clientSocket.send(sendData.encode("utf-8"))
recvData = clientSocket.recv(1024)
print("服務(wù)器說:%s" % (recvData.decode("utf-8"))) # 解碼:將二進(jìn)制轉(zhuǎn)換成字符
1、在TCP中,客戶端的實(shí)現(xiàn)流程:
創(chuàng)建客戶端的socket對(duì)象建立與服務(wù)器之間的聯(lián)系發(fā)送請(qǐng)求接收數(shù)據(jù)關(guān)閉連接
2、服務(wù)端的實(shí)現(xiàn)流程:
創(chuàng)建服務(wù)端的socket對(duì)象綁定服務(wù)端的地址設(shè)置監(jiān)聽器等待客戶端的連接接收客戶端的請(qǐng)求返回處理的結(jié)果到客戶端
ThreadingTCPServer 多線程多客戶端通信自動(dòng)重連demo
socketserver繼承圖:
![[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-RP9L9E1X-1577626400313)(../../../markdown_pic/blog_socketserver.png)]](http://img.jbzj.com/file_images/article/201912/2019123114212523.png)
TCPServer
# from socketserver import TCPServer, BaseRequestHandler, ThreadingTCPServer
from socketserver import TCPServer, StreamRequestHandler, ThreadingMixIn
import traceback
# class MyBaseRequestHandler(BaseRequestHandler):
class MyBaseRequestHandler(StreamRequestHandler):
def handle(self):
self.addr = self.request.getpeername()
self.server.users[self.addr[1]] = self.request
message = "IP " + self.addr[0] + ":" + str(self.addr[1]) + " Connected..."
print(message)
while True:
try:
data = self.request.recv(1024).decode('UTF-8', 'ignore').strip()
print(f'receive from {self.client_address}:{data}')
back_data = (f"response\"" + data + "\":\n").encode("utf8")
self.request.sendall(back_data)
except:
traceback.print_exc()
break
# 源碼:class ThreadingTCPServer(ThreadingMixIn, TCPServer): pass
# 從ThreadingMixIn和TCPServer繼承,實(shí)現(xiàn)多線程
class MyThreadingTCPServer(ThreadingMixIn, TCPServer):
def __init__(self, server_address, RequestHandlerClass):
TCPServer.__init__(self, server_address, RequestHandlerClass)
self.users = {}
class MyTCPserver():
def __init__(self, server_addr='192.168.1.109', server_port=23):
self.server_address = server_addr
self.server_port = server_port
self.server_tuple = (self.server_address, self.server_port)
def run(self):
# server = TCPServer(self.server_tuple, MyBaseRequestHandler)
server = MyThreadingTCPServer(self.server_tuple, MyBaseRequestHandler)
server.serve_forever()
if __name__ == '__main__':
myserver = MyTCPserver()
myserver.run()
在telnet 下開啟開啟兩個(gè)客戶端,本電腦的IP為192.168.1.109,開兩個(gè)客戶端后,TCPServer的終端出現(xiàn)同一個(gè)IP但是不同端口的連接:
![[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-LRSXfXoG-1577626400318)(../../../markdown_pic/blog_TCPServer.png)]](http://img.jbzj.com/file_images/article/201912/2019123114212524.png)
TCPClient
import socket
import time
class MyClient:
host = '192.168.1.109'
port = 23
bufsiz = 1024
addr = None
skt = None
def __init__(self, host=None, port=None):
if host != None:
self.host = host
if port != None:
self.port = port
if self.addr == None:
self.addr = (self.host, self.port)
self.doConnection()
def doConnection(self):
try:
self.skt = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.skt.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
print(self.addr)
self.skt.connect(self.addr)
except:
pass
def run(self):
while True:
try:
_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
self.skt.sendall(f'{_time}:i am clent1 '.encode('utf-8'))
data = self.skt.recv(self.bufsiz)
print(data.decode('utf-8', 'ignore'))
if not data:
break
print(data.strip())
time.sleep(5)
except socket.error:
print('socket error, reconnection') # 自動(dòng)重連
time.sleep(3)
self.doConnection()
except:
print('other error')
self.skt.close()
myclient = MyClient()
myclient.run()
上面用的是telnet工具來作為客戶端,這里是用代碼實(shí)現(xiàn)模擬的客戶端。

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
jupyter notebook oepncv 顯示一張圖像的實(shí)現(xiàn)
這篇文章主要介紹了jupyter notebook oepncv 顯示一張圖像的實(shí)現(xiàn),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-04-04
Django?Rest?Framework實(shí)現(xiàn)身份認(rèn)證源碼詳解
這篇文章主要為大家介紹了Django?Rest?Framework實(shí)現(xiàn)身份認(rèn)證源碼詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05
Python?加載?TensorFlow?模型的注意事項(xiàng)
TensorFlow支持多種模型格式,但最常見的兩種是SavedModel和HDF5(對(duì)于Keras模型),這里,我將分別給出加載這兩種模型格式的示例代碼,需要的朋友可以參考下2024-08-08
python基礎(chǔ)學(xué)習(xí)之生成器與文件系統(tǒng)知識(shí)總結(jié)
本文是參考《python數(shù)據(jù)分析》的附錄對(duì)生成器和文件系統(tǒng)結(jié)合案例的一個(gè)簡單回顧,文中對(duì)python生成器與文件系統(tǒng)作了非常詳細(xì)的介紹,對(duì)正在學(xué)習(xí)python的小伙伴們有很好地幫助,需要的朋友可以參考下2021-05-05
python requests包的request()函數(shù)中的參數(shù)-params和data的區(qū)別介紹
這篇文章主要介紹了python requests包的request()函數(shù)中的參數(shù)-params和data的區(qū)別介紹,具有很好參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-05-05
在前女友婚禮上用python把婚禮現(xiàn)場的WIFI名稱改成了
大家好,我是Lex 喜歡欺負(fù)超人那個(gè)Lex 擅長領(lǐng)域:python開發(fā),網(wǎng)絡(luò)安全滲透,Windows域控Exchange架構(gòu) 今日重點(diǎn):python暴力拿下WiFi密碼;python拿下路由器管理頁面 代碼干貨滿滿,建議收藏+實(shí)操!有問題及需要,請(qǐng)留言哦2021-08-08
Python 進(jìn)程之間共享數(shù)據(jù)(全局變量)的方法
今天小編就為大家分享一篇Python 進(jìn)程之間共享數(shù)據(jù)(全局變量)的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-07-07

