-
Notifications
You must be signed in to change notification settings - Fork 1
/
session.repy
91 lines (69 loc) · 2.64 KB
/
session.repy
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
# This module wraps communications in a signaling protocol. The purpose is to
# overlay a connection-based protocol with explicit message signaling.
#
# The protocol is to send the size of the message followed by \n and then the
# message itself. The size of a message must be able to be stored in
# sessionmaxdigits. A size of -1 indicates that this side of the connection
# should be considered closed.
#
# Note that the client will block while sending a message, and the receiver
# will block while recieving a message.
#
# While it should be possible to reuse the connectionbased socket for other
# tasks so long as it does not overlap with the time periods when messages are
# being sent, this is inadvisable.
class SessionEOF(Exception):
pass
sessionmaxdigits = 20
# get the next message off of the socket...
def session_recvmessage(socketobj):
messagesizestring = ''
# first, read the number of characters...
for junkcount in range(sessionmaxdigits):
currentbyte = socketobj.recv(1)
if currentbyte == '\n':
break
# not a valid digit
if currentbyte not in '0123456789' and messagesizestring != '' and currentbyte != '-':
raise ValueError, "Bad message size"
messagesizestring = messagesizestring + currentbyte
else:
# too large
raise ValueError, "Bad message size"
try:
messagesize = int(messagesizestring)
except ValueError:
raise ValueError, "Bad message size"
# nothing to read...
if messagesize == 0:
return ''
# end of messages
if messagesize == -1:
raise SessionEOF, "Connection Closed"
if messagesize < 0:
raise ValueError, "Bad message size"
data = ''
while len(data) < messagesize:
chunk = socketobj.recv(messagesize-len(data))
if chunk == '':
raise SessionEOF, "Connection Closed"
data = data + chunk
return data
# a private helper function
def session_sendhelper(socketobj,data):
sentlength = 0
# if I'm still missing some, continue to send (I could have used sendall
# instead but this isn't supported in repy currently)
while sentlength < len(data):
thissent = socketobj.send(data[sentlength:])
sentlength = sentlength + thissent
# send the message
def session_sendmessage(socketobj,data):
header = str(len(data)) + '\n'
# Sending these piecemeal does not accomplish anything, and can contribute
# to timeout issues when run by constantly overloaded machines.
# session_sendhelper(socketobj,header)
# Concatenate the header and data, rather than sending both separately.
complete_packet = header + data
# session_sendhelper(socketobj,data)
session_sendhelper(socketobj, complete_packet)