Python Socket編程詳細介紹
在使用Python做socket編程時,由于需要使用阻塞(默認)的方式來讀取數(shù)據(jù)流,此時對于數(shù)據(jù)的結(jié)束每次都需要自己處理,太麻煩。并且網(wǎng)上也沒找到太好的封裝,所以就自己寫了個簡單的封裝。
封裝思路
1. 客戶端每次請求均發(fā)送一個 SocketRequest 對象,其中封裝具體的數(shù)據(jù),這里使用json。對于要發(fā)送的數(shù)據(jù),會自動添加一個結(jié)束符標識(EOF = ‘0x00')。
2. 服務器端接收數(shù)據(jù)時,根據(jù)結(jié)束符標識來生成完整的數(shù)據(jù),并解包成 SocketRequest 對象。
3. 服務器端根據(jù) SocketRequest 的內(nèi)容,來生成 SocketResponse 對象,這里使用了一個 SimpleRequestHandler 類來處理,例子中就是沒有做任何處理,然后原樣返回。
4. 服務器端發(fā)送 SocketResponse 給客戶端。其中也需要對包做一個封裝,會自動添加一個結(jié)束符標識(EOF = ‘0x00')。
5. 客戶接收數(shù)據(jù)時,根據(jù)結(jié)束符標識來生成完整的數(shù)據(jù),并解包成 SocketResponse 對象,然后返回。
封裝類
sockets.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import socket
import pickle
import thread
PORT = 12345
EOF = '0x00'
class SocketServer(object):
def __init__(self, port=None):
self.port = port
def startup(self):
sock_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock_server.bind(('0.0.0.0', self.port))
sock_server.listen(0)
while True:
sock, address = sock_server.accept()
thread.start_new_thread(self.__invoke, (sock, address))
def shutdown(self):
pass
def __invoke(self, sock, address):
try:
full_data = ''
while True:
data = sock.recv(1024)
if data is None:
return
full_data += data
if full_data.endswith(EOF):
full_data = full_data[0:len(full_data) - len(EOF)]
request = pickle.loads(full_data)
response = SimpleRequestHandler().handle(request)
sock.sendall(pickle.dumps(response) + EOF)
return
except Exception as e:
print e
finally:
sock.close()
class SocketClient(object):
def __init__(self, host, port):
self.host = host
self.port = port
def execute(self, request):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((self.host, self.port))
try:
sock.sendall(pickle.dumps(request) + EOF)
full_data = ''
while True:
data = sock.recv(1024)
if data:
full_data += data
if full_data.endswith(EOF):
full_data = full_data[0:len(full_data) - len(EOF)]
response = pickle.loads(full_data)
return response
else:
return None
except Exception as e:
print e
return None
finally:
sock.close()
class SocketRequest(object):
def __init__(self, data):
self.data = data
def __repr__(self):
return repr(self.__dict__)
class SocketResponse(object):
def __init__(self, data):
self.data = data
def __repr__(self):
return repr(self.__dict__)
class SimpleRequestHandler(object):
def __init__(self):
pass
def __repr__(self):
return repr(self.__dict__)
def handle(self, request):
return SocketResponse(request.data)
測試
socket_server.py
#!/usr/bin/env python # -*- coding: utf-8 -*- from agent.sockets import * ss = SocketServer(PORT) ss.startup()
socket_client.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import pickle
from agent.sockets import *
sc = SocketClient('localhost', PORT)
request = SocketRequest('abc')
response = sc.execute(request)
print request
print response
運行測試
首先,運行 socket_server.py
然后,運行 socket_client.py
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
Jupyter notebook 輸出部分顯示不全的解決方案
這篇文章主要介紹了Jupyter notebook 輸出部分顯示不全的解決方案,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-04-04
使用python matploblib庫繪制準確率,損失率折線圖
這篇文章主要介紹了使用python matploblib庫繪制準確率,損失率折線圖,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-06-06
Python IDLE 錯誤:IDLE''''s subprocess didn''''t make connectio
這篇文章主要介紹了Python IDLE 錯誤:IDLE's subprocess didn't make connection 的解決方案的相關資料,需要的朋友可以參考下2017-02-02
Python mplfinance庫繪制金融圖表實現(xiàn)數(shù)據(jù)可視化實例探究
mplfinance(Matplotlib Finance),它是基于Matplotlib的庫,專門用于創(chuàng)建金融圖表和交互式金融數(shù)據(jù)可視化,本文將深入介紹?mplfinance,包括其基本概念、功能特性以及如何使用示例代碼創(chuàng)建各種金融圖表2024-01-01
python訓練數(shù)據(jù)時打亂訓練數(shù)據(jù)與標簽的兩種方法小結(jié)
今天小編就為大家分享一篇python訓練數(shù)據(jù)時打亂訓練數(shù)據(jù)與標簽的兩種方法小結(jié),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-11-11

