Advertisement
Guest User

Untitled

a guest
Feb 21st, 2018
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.00 KB | None | 0 0
  1. import select
  2. import socket
  3. import pickle
  4. import re
  5.  
  6. TCP_IP = ''
  7. TCP_PORT = 8080
  8. BUFFER_SIZE = 4096
  9.  
  10. server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  11. server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  12. server_socket.bind((TCP_IP, TCP_PORT))
  13. server_socket.listen(5)
  14. print("Listening on port %d" % TCP_PORT)
  15.  
  16. # Dictionary of sockets to usernames, to stop multiple login
  17. # on a single account, etc
  18. socket_to_username = {}
  19. # users[username] = [socket, queue]
  20. # queue is a list of strings, a users messages
  21. users = {}
  22.  
  23.  
  24.  
  25.  
  26.  
  27.  
  28.  
  29. # Create username `username` and assign it to `s`. Succeeds if `username` is
  30. # not already taken; returns a failure message otherwise. Rejects usernames
  31. # that are not alphanumeric or underscore.
  32. def create(s, username):
  33. if not re.match("^\w+$", username):
  34. # The username is invalid. Return failure.
  35. print("Username %s is invalid." % username)
  36. response = {}
  37. response["TYPE"] = "FAILURE"
  38. response["MESSAGE"] = "USERNAME MUST BE ONE OR MORE ALPHANUMERICS OR UNDERSCORES"
  39. return response
  40. if username in users:
  41. # The username is already taken. Return failure.
  42. print("Username %s is already taken." % username)
  43. response = {}
  44. response["TYPE"] = "FAILURE"
  45. response["MESSAGE"] = "NON UNIQUE USERNAME"
  46. return response
  47. else:
  48. # The username is valid. Add it to the list.
  49. print("Creating user %s." % username)
  50. users[username] = [0, []]
  51. response = {}
  52. response["TYPE"] = "SUCCESS"
  53. response["MESSAGE"] = username
  54. return response
  55.  
  56.  
  57. # Logout socket `s` from account `username`. Returns a failure message
  58. # otherwise. Assumes that `s` is logged into account `username`.
  59. def logout(s, username=''):
  60. if not username and s in socket_to_username:
  61. username = socket_to_username[s]
  62. if s not in socket_to_username:
  63. return
  64. socket_to_username.pop(s)
  65. if username in users:
  66. users[username][0] = 0
  67. response = {}
  68. response["TYPE"] = "SUCCESS"
  69. response["MESSAGE"] = username
  70. return response
  71.  
  72.  
  73. # Assign `username` to `s`. Succeeds if `username` exists and is not assigned
  74. # to another socket. Returns a failure message otherwise.
  75. def login(s, username):
  76. if s in socket_to_username:
  77. response = {}
  78. response["TYPE"] = "FAILURE"
  79. response["MESSAGE"] = "LOGOUT FIRST"
  80. return response
  81.  
  82.  
  83. # Check that the username exists.
  84. if username in users:
  85. # Check that the username doesn't belong to someone else
  86. if users[username][0]:
  87. response = {}
  88. response["TYPE"] = "FAILURE"
  89. response["MESSAGE"] = "USERNAME ALREADY LOGGED IN"
  90. return response
  91.  
  92. socket_to_username[s] = username
  93. users[username][0] = s
  94. response = {}
  95. response["TYPE"] = "SUCCESS"
  96. response["MESSAGE"] = username
  97. return response
  98. else:
  99. response = {}
  100. response["TYPE"] = "FAILURE"
  101. response["MESSAGE"] = "UNKNOWN USERNAME"
  102. return response
  103.  
  104.  
  105. # Returns a list of usernames that satisfies regular expression `regex`.
  106. # Returns a failure message if the regular expression is bad.
  107. def grep(regex='.*'):
  108. try:
  109. ret = []
  110. for user in users.keys():
  111. if (re.match(regex, user)):
  112. ret.append(user)
  113. response = {}
  114. response["TYPE"] = "SUCCESS"
  115. response["MESSAGE"] = ret
  116. return response
  117. except re.error:
  118. response = {}
  119. response["TYPE"] = "FAILURE"
  120. response["MESSAGE"] = "INVALID REGEX"
  121. return response
  122.  
  123.  
  124. # Sends message `message` from `username` to `recipient`.
  125. def send(username, recipient, message):
  126. if recipient not in users:
  127. response = {}
  128. response["TYPE"] = "FAILURE"
  129. response["MESSAGE"] = "UNKNOWN USERNAME"
  130. return response
  131.  
  132. packet = {}
  133. packet["TYPE"] = "MESSAGE"
  134. packet["SENDER"] = username
  135. packet["MESSAGE"] = message
  136.  
  137. if users[recipient][0]:
  138. # Recipient logged in; deliver immediately
  139. s = users[recipient][0]
  140. try:
  141. s.sendall(pickle.dumps(packet));
  142. response = {}
  143. response["TYPE"] = "SUCCESS"
  144. response["MESSAGE"] = "USER LOGGED IN"
  145. return response
  146. except:
  147. # Message failed partway
  148. users[recipient][1].append(packet)
  149. response = {}
  150. response["TYPE"] = "SUCCESS"
  151. response["MESSAGE"] = "USER NOT LOGGED IN"
  152. return response
  153.  
  154. # Recipient not logged in
  155. users[recipient][1].append(packet)
  156.  
  157. response = {}
  158. response["TYPE"] = "SUCCESS"
  159. response["MESSAGE"] = "USER NOT LOGGED IN"
  160. return response
  161.  
  162.  
  163. # Deliver the contents of the message queue to `recipient`.
  164. def deliver(recipient):
  165. if recipient not in users:
  166. response = {}
  167. response["TYPE"] = "FAILURE"
  168. response["MESSAGE"] = "UNKNOWN USERNAME"
  169. return response
  170.  
  171. if users[recipient][0]:
  172. # Recipient logged in; deliver messages
  173. s = users[recipient][0]
  174. messages_sent = 0
  175. for i in range(len(users[recipient][1])):
  176. packet = users[recipient][1][messages_sent]
  177. try:
  178. s.sendall(pickle.dumps(packet));
  179. messages_sent += 1
  180. except:
  181. # Message failed partway
  182. break
  183.  
  184. users[recipient][1] = users[recipient][1][messages_sent:]
  185. response = {}
  186. response["TYPE"] = "SUCCESS"
  187. response["MESSAGE"] = "DELIVERED USER " + str(messages_sent) + " MESSAGES"
  188. return response
  189.  
  190. # Recipient not logged in
  191. response = {}
  192. response["TYPE"] = "FAILURE"
  193. response["MESSAGE"] = "USER NOT LOGGED IN"
  194. return response
  195.  
  196.  
  197. # Delete user `to_delete`.
  198. def delete(to_delete):
  199. s = 0
  200. if (to_delete in users):
  201. s, _ = users.pop(to_delete)
  202. if s:
  203. print(s, socket_to_username[s])
  204. del socket_to_username[s]
  205. try:
  206. s.sendall(pickle.dumps({"TYPE": "ERROR", "MESSAGE": "YOUR ACCOUNT HAS BEEN DELETED"}))
  207. except:
  208. pass
  209.  
  210. return {"TYPE": "SUCCESS", "MESSAGE": to_delete}
  211. else:
  212. return {"TYPE": "FAILURE", "MESSAGE": "UNKNOWN USERNAME"}
  213.  
  214.  
  215. # Handle a request from `s` for `request`.
  216. def handleRequest(s, request):
  217. if request["TYPE"] == "create":
  218. username = request["MESSAGE"]
  219. return create(s, username)
  220.  
  221. if request["TYPE"] == "login":
  222. username = request["MESSAGE"]
  223. return login(s, username)
  224.  
  225. if request["TYPE"] == "list":
  226. regex = request["MESSAGE"]
  227. return grep(regex)
  228.  
  229. if s not in socket_to_username:
  230. # The user is not yet logged in
  231. response = {}
  232. response["TYPE"] = "FAILURE"
  233. response["MESSAGE"] = "NOT LOGGED IN"
  234. return response
  235.  
  236. username = socket_to_username[s]
  237.  
  238. if request["TYPE"] == "logout":
  239. return logout(s, username)
  240.  
  241. if request["TYPE"] == "send":
  242. recipient = request["RECIPIENT"]
  243. message = request["MESSAGE"]
  244. return send(username, recipient, message)
  245.  
  246. if request["TYPE"] == "deliver":
  247. recipient = request["MESSAGE"]
  248. return deliver(recipient)
  249.  
  250. if request["TYPE"] == "delete":
  251. to_delete = request["MESSAGE"]
  252. return delete(to_delete)
  253.  
  254. response = {}
  255. response["TYPE"] = "FAILURE"
  256. response["MESSAGE"] = "COMMAND NOT FOUND"
  257. return response
  258.  
  259. def sendError(s, message):
  260. try:
  261. response = {}
  262. response["TYPE"] = "FAILURE"
  263. response["MESSAGE"] = message
  264. s.sendall(pickle.dumps(response))
  265. except:
  266. pass
  267.  
  268.  
  269. read_list = [server_socket]
  270. while True:
  271. # This is how we avoid threading
  272. # It constantly looks to everything in readlist to read from
  273. readable, writable, errored = select.select(read_list, [], [])
  274. print(readable)
  275. for s in readable:
  276. # Somebody is trying to connect
  277. if s is server_socket:
  278. client_socket, address = server_socket.accept()
  279. read_list.append(client_socket)
  280. print("Connection from", address)
  281. else:
  282. data = s.recv(BUFFER_SIZE)
  283. if data:
  284. try:
  285. # Handle it and send to appropriate people
  286. request = pickle.loads(data)
  287. response = handleRequest(s, request)
  288. s.sendall(pickle.dumps(response))
  289. except Exception as e:
  290. print("Error encountered with %s." % data)
  291. print(e)
  292. sendError(s, "UNKNOWN ERROR")
  293. # They sent us a "I died" message
  294. else:
  295. s.close()
  296. logout(s)
  297. read_list.remove(s)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement