Ramsey's CSI 470 - Computer Networks
Server protocol:
The idea was to update any packet sent to be in the format: 3
digits + message of length described by the three digits. I
promised you an update to sendMsg and recvMsg that would handle
this new format. That is below.
-The server will be doing a select on a server socket, all client
sockets and optionally stdin.
-The server will keep a dictionary (let's call it names) that
correlates "client socket" keys to "client login names"
-If a client socket is not in the dictionary then that client has not
logged in yet.
-The server will keep a dictionary (let's call it logins) that
correlates login names to passwords.
-If the select indicates that the server socket needs to do something,
then the server socket should accept the incoming connection and add
that client socket to the list of things it is selecting on
-The server will keep a list of the names of currently logged in
users. Let's c all this (loggedInUsers)
Otherwise, the server will respond to things sent by a client socket:
MSG message - if a client sends MSG, the server must first check if
they are logged in by checking the names dictionary. If so, the
server will delete MSG and add the sending clients name to the front
of the rest of string (by doing a lookup into the names
dictionary). The server will then send this message to all
clients. If the client is not logged in, the server will send NO to
the client.
LOGIN username password - the server should check that both the
username and password are alphanumeric (isalnum in python). the
server shall add username and password to the logins dictionary if
they don't already exist. If the dictionary already has the
username, then the server should check that the password matches the
existing password. On a successful match, an OK will be sent to the
client. On a failed match, a NO will be sent to the client. If OK is
sent, a message to all other clients should be sent describing that
the user has logged in. If an OK is sent, the client socket/name
should be added to the names dictionary and the name should be added
to the loggedInUsers list. Lastly, be careful when doing a split on
this message that there are actually 3 pieces or else your server
will crash. Usernames of "MSG, LOGIN, BYE, OK, NO, W, and WHO" are
forbidden and your server should protect these by sending a NO and
not logging in that request.
W username message - this is optional for the server to handle. Be
sure to catch all the error cases. You'll likely need a dictionary
that does the reverse lookup of the names dictionary.
WHO - when this is sent, the server will compile a list of names of
currently logged in clients and send it to the client that sent the
WHO message. This list is maintained in the loggedInUsers list.
BYE - no message is sent to the client. If the socket exists in the
names dictionary, then it should be removed from the names
dictionary. If that socket's name from the names dictionary exists
in the loggedInUsers list, then it should be removed. (Be careful
with the ordering of those operations). The server should remove the
client's socket from the list that it is selecting from as well. In
the event that the name did exist in the names dictionary or
loggedInUsers list then a message should be sent to all other
clients that this user has logged out. (The same process should
happen if the try catch around socket.error is triggered).
----- new send/recv
def sendMsg(s,msg):
l = len(msg)
nm = ''
if l < 10:
nm = '00' + str(l)
elif l < 100:
nm = '0'+str(l)
elif l > 999: #message is way too long
nm = '999'
else :
nm = str(l)
s.send(nm)
# print 'Sending ' + nm + ' ' + msg[:996] + ' length= ' + str(len(nm+' '+msg[:996]))
s.send(msg[:996])
def recvMsg(c):
l1 = c.recv(3)
# print 'Received (' + l1 + ')'
try:
val = int(l1)
except ValueError:
print 'Error in recv'
return ' - ' # might optionally return nil/null here and check it
if val == 0:
print ' Error: Receiving 0 is weird!'
return ' - '
msg = c.recv(val)
#print 'Msg is ' + msg
return msg;