在使用Python做socket編程時,由于需要使用阻塞(默認)的方式來讀取數據流,此時對于數據的結束每次都需要自己處理,太麻煩。并且網上也沒找到太好的封裝,所以就自己寫了個簡單的封裝。
封裝思路
1. 客戶端每次請求均發送一個 SocketRequest 對象,其中封裝具體的數據,這里使用json。對于要發送的數據,會自動添加一個結束符標識(EOF = ‘0x00')。
2. 服務器端接收數據時,根據結束符標識來生成完整的數據,并解包成 SocketRequest 對象。
3. 服務器端根據 SocketRequest 的內容,來生成 SocketResponse 對象,這里使用了一個 SimpleRequestHandler 類來處理,例子中就是沒有做任何處理,然后原樣返回。
4. 服務器端發送 SocketResponse 給客戶端。其中也需要對包做一個封裝,會自動添加一個結束符標識(EOF = ‘0x00')。
5. 客戶接收數據時,根據結束符標識來生成完整的數據,并解包成 SocketResponse 對象,然后返回。
封裝類
sockets.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
#!/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
1
2
3
4
5
6
|
#!/usr/bin/env python # -*- coding: utf-8 -*- from agent.sockets import * ss = SocketServer(PORT) ss.startup() |
socket_client.py
1
2
3
4
5
6
7
8
9
10
11
|
#!/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
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:http://blog.csdn.net/kongxx/article/details/64951241