TiledViz
Loading...
Searching...
No Matches
sock.py
1# -*- coding: utf-8 -*-
2
3import socket
4import sys,os,stat, errno
5import logging
6import platform
7import configparser
8
9import time,datetime
10
11from .transfer import hashfile,readblock
12
13TVrunDir=os.environ['HOME']+'/.tiledviz'
14TVconf=TVrunDir+"/tiledviz.conf"
15configExist=False
16if (os.path.isdir(TVrunDir)):
17 if (os.path.isfile(TVconf)):
18 configExist=True
19else:
20 os.mkdir(TVrunDir)
21 mode = os.stat(TVrunDir).st_mode
22 mode -= (mode & (stat.S_IRWXG | stat.S_IRWXO))
23 os.chmod(TVrunDir,mode)
24
25if (configExist):
26 config = configparser.ConfigParser()
27 config.optionxform = str
28 config.read(TVconf)
29
30 # Default port for connection between client in sock.py and TVSecure.py
31 PORTServer=int(config['sock']['PORTServer'])
32
33 # Message fix size for data transfert through socket
34 MSGsize=int(config['sock']['MSGsize'])
35else:
36 # Default port for connection between client in sock.py and TVSecure.py
37 PORTServer=55554
38
39 # Message fix size for data transfert through socket
40 MSGsize=1024
41
42logFormatter = logging.Formatter("%(asctime)s - sock - %(threadName)s - %(levelname)s: %(message)s ")
43#logging.basicConfig(level=logging.WARNING)
44sockLogger = logging.getLogger("sock")
45#sockLogger.setLevel(logging.ERROR)
46sockLogger.setLevel(logging.WARNING)
47#sockLogger.setLevel(logging.INFO)
48#sockLogger.setLevel(logging.DEBUG)
49#sockLogger.setLevel(9)
50outHandler = logging.StreamHandler(sys.stdout)
51outHandler.setFormatter(logFormatter)
52sockLogger.addHandler(outHandler)
53
54class client:
55 def __init__(self,port=PORTServer):
56 self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
57 self.s.connect(('localhost', port))
58 sockLogger.log(9,str(self.s))
59
60 Hostname=os.getenv("HOSTNAME", os.getenv('COMPUTERNAME', platform.node())).split('.')[0]
61 HelloMsg=('Connection from '+Hostname).encode('utf-8').ljust(MSGsize,b'\00')
62 sockLogger.warning(HelloMsg.rstrip(b'\00'))
63 self.s.sendall(HelloMsg)
64
65 data = self.s.recv(MSGsize).rstrip(b'\00')
66 sockLogger.info('Received my hostname from server : %s' % (repr(data)))
67
68 def send_server(self,command):
69 sockLogger.log(9,"Send command '%s' to server." % (command))
70 self.s.sendall(command.replace(" "," ").encode('utf-8').ljust(MSGsize,b'\00'))
71
72 def receive(self,nb):
73 while True:
74 sockLogger.log(9,"Wait for receive %d octets." % (nb))
75 try:
76 data = self.s.recv(nb)
77 except socket.error as serr:
78 if serr.errno != errno.ECONNREFUSED:
79 # Not the error we are looking for, re-raise
80 #raise serr
81 #errno If using Python 3.3 it now has ConnectionRefusedError and socket.error is deprecated.
82 sockLogger.error("Error not ECONNREFUSED.")
83 sockLogger.error("Error with connection to server. we quit with error %s " % (str(serr.errno)))
84 sys.exit(serr.errno)
85 # errno.ECONNABORTED
86 # errno.ECONNRESET
87
88 if not data: return False
89 break
90 data_ = str(data.rstrip(b'\x00').decode('utf-8'))
91 return data_
92
93 def recv(self):
94 messg=self.receive(MSGsize)
95 sockLogger.log(9,"Receive '%s' from server." % (messg))
96 return messg
97
98 def send_OK(self,iRET):
99 if not type(iRET)==int:
100 sockLogger.log(9,"iRET"+str(type(iRET)))
101 self.s.sendall('ff'.encode('utf-8'))
102 else:
103 sRET=hex(iRET).replace('0x',"").encode('utf-8')
104 if (len(sRET) < 2):
105 sRET=b'0'+sRET
106 elif(len(sRET)>2):
107 sRET=sRET[(len(sRET)-2):len(sRET)]
108 self.s.sendall(sRET)
109
110 def get_OK(self):
111 RET=self.receive(2)
112 sockLogger.log(9,"Wait for OK from server : "+str(RET))
113 intRET=-1
114 if not RET: return intRET
115 try:
116 intRET=int(RET,16)
117 except:
118 sockLogger.error("OK error from server : "+str(RET)+self.receive(MSGsize-2))
119 return intRET
120
121 def send_file(self, path, filename):
122 filein=os.path.join(path,filename)
123 sockLogger.warning("Send data from file %s." % (filein))
124
125 totbyte=0
126 filesize=os.path.getsize(filein)
127 f = open(filein,'rb')
128 if (filesize < MSGsize):
129 l = f.read(filesize).ljust(MSGsize,b'\00')
130 else:
131 l = f.read(MSGsize)
132 #iter=0
133
134 while (l):
135 self.s.send(l)
136 totbyte=totbyte+MSGsize
137 # iter=iter+1
138 # sockLogger.error("Client iter %d" % (iter))
139 rest=filesize-totbyte;
140 if (rest > MSGsize ):
141 l = f.read(MSGsize)
142 else:
143 if (rest > 0):
144 l = f.read(rest).ljust(MSGsize,b'\00')
145 self.s.send(l)
146 # iter=iter+1
147 # sockLogger.error("Client rest %d iter %d" % (rest,iter))
148 break
149
150 f.close()
151 sockLogger.warning("File sent.")
152
153 def get_file(self, path, filename, filesize, filesha256):
154 fileout=os.path.join(path,os.path.basename(filename))
155 sockLogger.info("Wait for data of size %d and hash %s." % (filesize,filesha256))
156 sockLogger.warning("Write data received from server in file %s." % (fileout))
157 self.send_OK(0)
158
159 Date=datetime.datetime.isoformat(datetime.datetime.now(),sep='_').replace(":","-")
160 if (os.path.exists(fileout)):
161 fileout_=fileout
162 fileout=fileout+'_'+Date
163 sockLogger.error("Can't overwrite existing file %s. Add date : %s" % (fileout_, fileout))
164
165 try:
166 f=open(fileout, 'wb')
167 totbyte=0
168 #iter=0
169 while True:
170 #iter=iter+1
171 #sockLogger.error("Server iter %d" % (iter))
172 data = self.s.recv(MSGsize)
173 if not data:
174 break
175 totbyte=totbyte+MSGsize
176 if totbyte < filesize:
177 f.write(data)
178 sockLogger.log(9,'data %d inf %d=%s' % (totbyte,filesize,str(data)))
179 else:
180 data=data.rstrip(b'\x00')
181 sockLogger.log(9,'data rest %d=%s' % (totbyte-filesize,str(data)))
182 f.write(data)
183 f.close()
184 break
185 except socket.error as serr:
186 sockLogger.error("Error with downloading file %s from %d : %s" % (str(fileout),id,str(serr)))
187 except Exception as e:
188 sockLogger.error("Unknown error with downloading file %s from %d : %s" % (str(fileout),id,str(e)))
189
190 # Test for size and sha256
191 sockLogger.log(9,'Test for size and sha256 ')
192 outsize = os.path.getsize(fileout)
193 #statinfo = os.stat(fileout)
194 #statinfo.st_size
195 if ( not outsize == filesize ):
196 sockLogger.error("File %s downloaded hasn't the size %d given by client : %d.\n It will be removed." % (fileout, filesize, outsize))
197 #os.remove(fileout)
198 self.send_OK(1)
199 return 1
200
201 filed=open(fileout, 'rb')
202 outsha256=hashfile(readblock(filed))
203 if ( outsha256 != filesha256 ):
204 sockLogger.error("File %s downloaded hasn't the size %d given by client : %d.\n It will be removed." % (fileout, filesize, outsize))
205 #os.remove(fileout)
206 self.send_OK(2)
207 return 1
208 self.send_OK(0)
209 return 0
210
211 def close(self):
212 self.s.close();
213
214
215class server:
216 def __init__(self, serverPORT):
217 self.tcpsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
218 self.tcpsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
219 self.tcpsock.bind(("",serverPORT))
220 self.tcpsock.listen(200)
221 self.clientsocket={}
222 self.clientinfos={}
223 self.clientids=[]
224
225 def new_connect(self,id):
226 (clientsocket, (ip, port)) = self.tcpsock.accept()
227 self.clientsocket[id]=clientsocket
228 self.clientids.append(id)
229 self.clientinfos[id]=(ip, port)
230 sockLogger.warning( "Accept port %d" % (port))
231 sockLogger.info( "Accept %s ip %s port %d" % (str(clientsocket), str(ip), port))
232
233 def send_client(self,id,command):
234 self.clientsocket[id].sendall(command.replace(" "," ").encode('utf-8').ljust(MSGsize,b'\00'))
235 # while True:
236 # self.s.recv(OK)
237 # if (int(OK)==1):
238 # break
239
240 def receive(self,id,nb):
241 sockLogger.log(9,"Wait from %d client for receive %d octets." % (id,nb))
242 try:
243 data = self.clientsocket[id].recv(nb)
244 except socket.error as serr:
245 if serr.errno != errno.ECONNREFUSED:
246 # Not the error we are looking for, re-raise
247 #raise serr
248 #errno If using Python 3.3 it now has ConnectionRefusedError and socket.error is deprecated.
249 sockLogger.error("Not ECONNREFUSED.")
250 sockLogger.error("Error with connection on client : %d . We quit with error %d " % (id , serr.errno))
251 sys.exit(serr.errno)
252 # errno.ECONNABORTED
253 # errno.ECONNRESET
254
255 if not data: return False
256 data_ = str(data.rstrip(b'\x00').decode('utf-8'))
257 return data_
258
259 def recv(self,id):
260 sockLogger.log(9,"wait for receive %d octets." % (MSGsize))
261 return self.receive(id,MSGsize)
262
263 def send_OK(self,id,iRET):
264 sockLogger.log(9,"Send to %d status %d." % (id,iRET))
265 sRET=hex(iRET).replace('0x',"").encode('utf-8')
266 if (len(sRET) < 2):
267 sRET=b'0'+sRET
268 elif(len(sRET)>2):
269 sRET=sRET[(len(sRET)-2):len(sRET)]
270 self.clientsocket[id].sendall(sRET)
271
272 def get_OK(self,id):
273 sockLogger.log(9,"Wait for OK from %d." % (id))
274 RET=self.receive(id,2)
275 if not RET: return -1
276 try:
277 RET1=int(RET,16)
278 except:
279 sockLogger.error(9," from OK from %d.: %s" % (id,str(RET)))
280 RET1=-1
281 return RET1
282
283 def get_file(self, id, path, filename, filesize, filesha256):
284 fileout=os.path.join(path,os.path.basename(filename))
285 sockLogger.warning("Write data received from %d in file %s." % (id,fileout))
286 sockLogger.info("Wait for data of size %d and hash %s." % (filesize,filesha256))
287 Date=datetime.datetime.isoformat(datetime.datetime.now(),sep='_').replace(":","-")
288 if (os.path.exists(fileout)):
289 fileout_=fileout
290 fileout=fileout+'_'+Date
291 sockLogger.error("Can't overwrite existing file %s. Add date : %s" % (fileout_, fileout))
292
293 try:
294 f=open(fileout, 'wb')
295 totbyte=0
296 # iter=0
297 while True:
298 # iter=iter+1
299 # sockLogger.error("Server iter %d" % (iter))
300 data = self.clientsocket[id].recv(MSGsize)
301 if not data:
302 break
303 totbyte=totbyte+MSGsize
304 if totbyte < filesize:
305 f.write(data)
306 # sockLogger.log(9,'data %d inf %d=%s' % (totbyte,filesize,str(data)))
307 else:
308 data=data.rstrip(b'\x00')
309 # sockLogger.log(9,'data rest %d=%s' % (totbyte-filesize,str(data)))
310 f.write(data)
311 f.close()
312 break
313 except socket.error as serr:
314 sockLogger.error("Error with downloading file %s from %d : %s" % (str(fileout),id,str(serr)))
315 except Exception as e:
316 sockLogger.error("Unknown error with downloading file %s from %d : %s" % (str(fileout),id,str(e)))
317
318 # Test for size and sha256
319 sockLogger.log(9,'Test for size and sha256 ')
320 outsize = os.path.getsize(fileout)
321 #statinfo = os.stat(fileout)
322 #statinfo.st_size
323 if ( not outsize == filesize ):
324 sockLogger.error("File %s downloaded hasn't the size %d given by client : %d.\n It will be removed." % (fileout, filesize, outsize))
325 #os.remove(fileout)
326 self.send_OK(id,1)
327 return 1
328
329 filed=open(fileout, 'rb')
330 outsha256=hashfile(readblock(filed))
331 if ( outsha256 != filesha256 ):
332 sockLogger.error("File %s downloaded hasn't the size %d given by client : %d.\n It will be removed." % (fileout, filesize, outsize))
333 #os.remove(fileout)
334 self.send_OK(id,2)
335 return 1
336 self.send_OK(id,0)
337
338 def send_file(self,id,path,filename):
339 filein=os.path.join(path,filename)
340 sockLogger.warning("Send data from file %s." % (filein))
341
342 if (os.path.exists(filein)):
343 self.send_OK(id,0)
344 filesize = os.path.getsize(filein)
345 filed=open(filein, 'rb')
346 filesha256=hashfile(readblock(filed))
347 filed.close()
348
349 totbyte=0
350
351 # Send filesize and filesha256 to client."
352 command="fileinfos %s %d %s" % (filename,filesize,filesha256)
353 sockLogger.info("Fileinfos sent to %d : %s." % (id,command))
354 self.send_client(id,command)
355 sockLogger.warning("Fileinfos sent : %s." % (str(self.get_OK(id))))
356
357 f = open(filein,'rb')
358 if (filesize < MSGsize):
359 l = f.read(filesize).ljust(MSGsize,b'\00')
360 else:
361 l = f.read(MSGsize)
362
363 #iter=0
364 while (l):
365 self.clientsocket[id].send(l)
366 totbyte=totbyte+MSGsize
367 #iter=iter+1
368 #sockLogger.error("Client iter %d" % (iter))
369 rest=filesize-totbyte;
370 if (rest > MSGsize ):
371 l = f.read(MSGsize)
372 else:
373 if (rest > 0):
374 l = f.read(rest).ljust(MSGsize,b'\00')
375 self.clientsocket[id].send(l)
376 #iter=iter+1
377 #sockLogger.error("Client rest %d iter %d" % (rest,iter))
378 break
379
380 f.close()
381 sockLogger.warning("File sent : %s." % (str(self.get_OK(id))))
382 self.send_OK(id,0)
383 return (filesize,filesha256)
384 else:
385 FileERROR="File %s does not exist." % (filein)
386 sockLogger.error(FileERROR)
387 # response to ask
388 self.send_OK(id,100)
389 self.send_client(id,FileERROR)
390 # response to send
391 self.send_OK(id,110)
392 return (0,0)
393
394 def close(self,id):
395 sockLogger.warning("Close client %d server %s." % (id,str(self.tcpsock)))
396 self.clientsocket[id].close()
397
398 def close_all(self):
399 sockLogger.warning("Close server %s." % (str(self.tcpsock)))
400 for id in self.clientids:
401 self.clientsocket[id].close()
402 time.sleep(2)
403 self.tcpsock.close();
send_OK(self, iRET)
Definition sock.py:98
receive(self, nb)
Definition sock.py:72
send_client(self, id, command)
Definition sock.py:233
send_OK(self, id, iRET)
Definition sock.py:263
receive(self, id, nb)
Definition sock.py:240
get_OK(self, id)
Definition sock.py:272