1
- from socket import socket , AF_INET , SOCK_STREAM , SOL_SOCKET , SO_REUSEADDR , gethostname
1
+ from socket import AF_INET , SOCK_STREAM , SOL_SOCKET , SO_REUSEADDR , SO_ERROR
2
+ from socket import gethostname
2
3
from select import select
3
- import utils
4
+ import utils , socket
4
5
5
6
6
7
class SocketClient :
@@ -9,8 +10,34 @@ def __init__(self, sock):
9
10
self .txbuff = ''
10
11
self .rxbuff = ''
11
12
self .connected = True
13
+ self .connecting = False
14
+
15
+ def __init__ (self , address , port ):
16
+ self .txbuff = ''
17
+ self .rxbuff = ''
18
+ self .connected = False
19
+ self .connecting = True
20
+
21
+ self .sock = socket .socket (AF_INET , SOCK_STREAM )
22
+ self .sock .setblocking (0 )
23
+ try :
24
+ self .sock .connect ((address , port ))
25
+ except socket .error , e :
26
+ pass
12
27
13
28
def run (self ):
29
+ if self .connecting :
30
+ rd , wr , err = select ([], [self .sock ], [self .sock ], 0 )
31
+ if len (wr )> 0 :
32
+ self .connecting = False
33
+ self .connected = True
34
+ connect_result = self .sock .getsockopt (SOL_SOCKET , SO_ERROR )
35
+ if connect_result != 0 :
36
+ self .close ()
37
+ return
38
+ if len (err )> 0 :
39
+ self .close ()
40
+ return
14
41
if not self .connected :
15
42
return
16
43
@@ -56,10 +83,14 @@ def send(self, data):
56
83
def close (self ):
57
84
self .sock .close ()
58
85
self .connected = False
86
+ self .connecting = False
59
87
60
88
def is_connected (self ):
61
89
return self .connected
62
90
91
+ def is_connecting (self ):
92
+ return self .connecting
93
+
63
94
class SocketServer :
64
95
def __init__ (self ):
65
96
self .server = None
@@ -70,12 +101,20 @@ def run(self):
70
101
for id in self .clients :
71
102
self .clients [id ].run ()
72
103
104
+ def connect (self , address , port ):
105
+ # Determine the next id to assign to socket
106
+ client = SocketClient (address , port )
107
+ while self .next_id in self .clients :
108
+ self .next_id = (self .next_id + 1 ) % 256
109
+ self .clients [self .next_id ] = client
110
+ return self .next_id
111
+
73
112
def listen (self , address , port ):
74
113
if not self .server is None :
75
114
self .server .close ()
76
115
self .server = None
77
116
try :
78
- server = socket (AF_INET , SOCK_STREAM )
117
+ server = socket . socket (AF_INET , SOCK_STREAM )
79
118
server .setsockopt (SOL_SOCKET , SO_REUSEADDR , 1 )
80
119
utils .try_bind (server , address , port )
81
120
server .listen (1 ) # No connection backlog
@@ -120,6 +159,11 @@ def is_connected(self, id):
120
159
return None
121
160
return self .clients [id ].is_connected ()
122
161
162
+ def is_connecting (self , id ):
163
+ if not id in self .clients :
164
+ return None
165
+ return self .clients [id ].is_connecting ()
166
+
123
167
def close (self , id ):
124
168
if not id in self .clients :
125
169
return None
@@ -137,6 +181,15 @@ def run(self, data):
137
181
else :
138
182
return '\x00 '
139
183
184
+ class CONNECT_Command :
185
+ def run (self , data ):
186
+ port = (ord (data [0 ]) << 8 ) + ord (data [1 ])
187
+ c = server .connect (data [2 :], port )
188
+ if c is None :
189
+ return ''
190
+ else :
191
+ return chr (c )
192
+
140
193
class ACCEPT_Command :
141
194
def run (self , data ):
142
195
c = server .accept ()
@@ -169,6 +222,14 @@ def run(self, data):
169
222
else :
170
223
return '\x00 '
171
224
225
+ class CONNECTING_Command :
226
+ def run (self , data ):
227
+ id = ord (data [0 ])
228
+ if server .is_connecting (id ):
229
+ return '\x01 '
230
+ else :
231
+ return '\x00 '
232
+
172
233
class CLOSE_Command :
173
234
def run (self , data ):
174
235
id = ord (data [0 ])
@@ -182,6 +243,8 @@ def init(command_processor):
182
243
command_processor .register ('l' , WRITE_Command ())
183
244
command_processor .register ('L' , CONNECTED_Command ())
184
245
command_processor .register ('j' , CLOSE_Command ())
246
+ command_processor .register ('c' , CONNECTING_Command ())
247
+ command_processor .register ('C' , CONNECT_Command ())
185
248
command_processor .register_runner (server )
186
249
187
250
def test ():
@@ -202,6 +265,20 @@ def test():
202
265
server .close (0 )
203
266
server .close (1 )
204
267
268
+ def test_client ():
269
+ from time import sleep
270
+ i = server .connect ('192.168.1.100' , 5555 )
271
+ while server .is_connecting (i ):
272
+ server .run ()
273
+ if not server .is_connected (i ):
274
+ print "error"
275
+ return
276
+ print "connected"
277
+ server .send (i , "test" )
278
+ server .run ()
279
+ server .close (i )
280
+ server .run ()
281
+
205
282
if __name__ == '__main__' :
206
- test ()
283
+ test_client ()
207
284
0 commit comments