Python3 网络通信 网络聊天室 文件传输

功能描述

该项目将实现一个文字和文件传输的客户端和服务器程序通信应用程序。它将传输和接收视频文件。

文本消息必须通过TCP与服务器通信,而客户端自己用UDP传输视频文件。

程序将支持一下功能:

  • 用户身份验证
  • 向服务器发布消息
  • 编辑或删除消息、读取消息
  • 从服务器发送消息
  • 读取活动用户的信息
  • 上传视频文件从一个用户到另一个用户

简要流程

  • 该项目将实现各种应用程序协议来实现以上功能。
  • 服务器将监听指定为命令行参数的端口,并等待客户端监听连接。
  • 客户端程序将发起一个与服务器的TCP连接。
  • 在连接建立后,用户将启动身份验证过程。客户端将与用户交互通过命令行界面。
  • 身份验证成功后,用户可以执行一系列命令
  • 最终登出
  • 客户端和服务器都必须打印有意义的提示消息

简要设计

  • Server: 使用一个类来保存每个客户端信息,包括用户名和IP地址的映射,并多线程开始接收每个客户端的处理程序。
  • Client: 三个线程:主线程为获取用户输入和发送到服务器,和一个线程为接收服务器响应,一个线程UDP传输文件

功能协议

  • Login: flag("Login") + username + password
  • MSG: flag("MSG") + message
  • EDT: flag("EDT") + msg_index + msg_time + new_msg
  • DLT: flag("DLT") + msg_index + msg_time
  • RDM: flag("RDM") + msg_time
  • ATU: flag("ATU")
  • OUT: flag("OUT")
  • UPD: flag("UDP") + username + filename

Usage

  • Serverpython server.py 端口号 最大密码尝试次数
  • Clientpython client.py 服务器IP 服务器端口 客户端UDP端口

效果展示



代码

client 点击查看代码

  1. import socket
  2. import threading
  3. import time
  4. import sys
  5. import os
  6. UDP_port = 6666
  7. LoginStatus = False
  8. TCP_running = True
  9. clientSocket = socket.socket()
  10. login_Event = threading.Event()
  11. response_Event = threading.Event()
  12. user_list = []
  13. USERNAME = ""
  14. # get IP address and port after ATU command
  15. def get_address_port_by_username(name):
  16. if len(user_list) == 0:
  17. print("[error] need run ATU command first")
  18. else:
  19. for i in user_list:
  20. user_info = i.split(", ")
  21. username = user_info[0]
  22. address = user_info[1]
  23. port = user_info[2]
  24. if username == name:
  25. return address, port
  26. return None
  27. # LOGIN
  28. def log_in(clientSocket,udp_port):
  29. global USERNAME
  30. print("Username: ", end="")
  31. name = input('')
  32. print("Password: ", end="")
  33. pwd = input('')
  34. FLAG = "LOGIN"
  35. USERNAME = name
  36. PWD = pwd
  37. login_msg = FLAG + "%%" + name + "%%" + PWD + "%%" + str(udp_port)
  38. clientSocket.send(login_msg.encode('utf-8'))
  39. def reponse_to_client(recv_msg):
  40. global TCP_running
  41. global LoginStatus
  42. global login_Event
  43. send_msg = ""
  44. recv_msg_list = []
  45. recv_msg_list = recv_msg.split("%%")
  46. res = True
  47. if len(recv_msg_list) != 0:
  48. flag = recv_msg_list[0]
  49. if (flag == "LOGIN"):
  50. TYPE = recv_msg_list[1]
  51. if(TYPE == "0"):
  52. LoginStatus = True
  53. else:
  54. LoginStatus = False
  55. # inform the main loop the result from server
  56. login_Event.set()
  57. print(recv_msg_list[2])
  58. elif (flag == "MSG"):
  59. print(recv_msg_list[1])
  60. elif flag == "EDT":
  61. TYPE = recv_msg_list[1]
  62. if (TYPE == "0"):
  63. edit_res = True
  64. else:
  65. edit_res = False
  66. print(recv_msg_list[2])
  67. elif (flag == "RDM"):
  68. txt = recv_msg_list[1:]
  69. for i in txt:
  70. print(i)
  71. pass
  72. elif (flag == "DLT"):
  73. TYPE = recv_msg_list[1]
  74. if (TYPE == "0"):
  75. del_res = True
  76. else:
  77. del_res = False
  78. print(recv_msg_list[2])
  79. pass
  80. elif (flag == "ATU"):
  81. NUM = recv_msg_list[1]
  82. if NUM == "0":
  83. print(recv_msg_list[2])
  84. else:
  85. txt = recv_msg_list[2:]
  86. for i in txt:
  87. print(i)
  88. user_list.append(i)
  89. elif (flag == "OUT"):
  90. TCP_running = False
  91. print(recv_msg_list[1])
  92. def read_server(s):
  93. global response_Event
  94. global TCP_running
  95. while TCP_running:
  96. # the thread always receive from server
  97. content = s.recv(2048).decode('utf-8')
  98. reponse_to_client(content)
  99. # inform the mian loop, resume it
  100. response_Event.set()
  101. # s.close()
  102. os._exit(1)
  103. def execute_command(clientSocket):
  104. response_Event.clear()
  105. while TCP_running:
  106. print("Enter one of the following commands (MSG, DLT, EDT, RDM, ATU, OUT, UPD): ", end="")
  107. msg = input('')
  108. if not msg:
  109. continue
  110. command = msg.split(" ")[0]
  111. if command == "MSG":
  112. if len(msg.split(" ")) < 2:
  113. print("need arguments")
  114. continue
  115. txt = msg.split(" ")[1:]
  116. msg = command + "%%" + ' '.join(txt)
  117. elif command == "EDT":
  118. if len(msg.split(" ")) < 2:
  119. print("[error] need arguments")
  120. continue
  121. args = msg.split(" ")[1:]
  122. index = args[0][1:]
  123. dt = ' '.join(args[1:5])
  124. txt = ' '.join(args[5:])
  125. msg = command + "%%" + index + "%%" + dt + "%%" + txt
  126. elif command == "DLT":
  127. if len(msg.split(" ")) < 2:
  128. print("[error] need arguments")
  129. continue
  130. args = msg.split(" ")[1:]
  131. index = args[0][1:]
  132. dt = ' '.join(args[1:])
  133. msg = command + "%%" + index + "%%" + dt
  134. pass
  135. elif command == "RDM":
  136. if len(msg.split(" ")) < 2:
  137. print("[error] need arguments")
  138. continue
  139. dt = ' '.join(msg.split(" ")[1:])
  140. msg = command + "%%" + dt
  141. elif command == "ATU":
  142. if len(msg.split(" ")) < 2:
  143. pass
  144. else:
  145. print("[error] too many arguments")
  146. continue
  147. pass
  148. elif command == "OUT":
  149. if len(msg.split(" ")) < 2:
  150. pass
  151. else:
  152. print("[error] too many arguments")
  153. continue
  154. pass
  155. elif command == "UPD":
  156. if len(msg.split(" ")) < 3:
  157. print("[error] need more arguments")
  158. continue
  159. else:
  160. UDP_send(msg.split(" ")[1], msg.split(" ")[2])
  161. continue
  162. else:
  163. print("[error] unknown command")
  164. continue
  165. clientSocket.send(msg.encode('utf-8'))
  166. # block, waiting for server response
  167. time.sleep(0.3)
  168. response_Event.wait(30)
  169. response_Event.clear()
  170. # mian func
  171. def tcp_start(server_IP, server_port, udp_port):
  172. global clientSocket
  173. clientSocket = socket.socket()
  174. clientSocket.connect((server_IP, server_port))
  175. TCP_t = threading.Thread(target=read_server, args=(clientSocket,)).start()
  176. # login
  177. while LoginStatus == False:
  178. log_in(clientSocket, udp_port)
  179. # waiting for server ...
  180. time.sleep(0.3)
  181. # block, waiting for server response
  182. login_Event.wait(30)
  183. login_Event.clear()
  184. if LoginStatus:
  185. # print("Debug: log in success")
  186. pass
  187. else:
  188. # print("Debug: log in fail")
  189. pass
  190. # commands
  191. execute_command(clientSocket)
  192. def UDP_send(username, filename):
  193. global USERNAME
  194. address, port = get_address_port_by_username(username)
  195. BUF_SIZE = 1024
  196. # print(address, port)
  197. server_addr = (address, int(port))
  198. client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  199. count = 0
  200. f = open(filename, 'rb')
  201. while True:
  202. if count == 0:
  203. # send the first message inculding filename
  204. data = "UDP%%"+USERNAME+"_"+filename
  205. client.sendto(data.encode('utf-8'), server_addr)
  206. data = f.read(BUF_SIZE)
  207. if str(data) != "b''":
  208. client.sendto(data, server_addr)
  209. else:
  210. client.sendto('end'.encode('utf-8'), server_addr) # end for the file and send a speical "end" flag
  211. # lecture1.mp4 has been uploaded
  212. print(filename + " has been uploaded.")
  213. execute_command(clientSocket)
  214. break
  215. count += 1
  216. time.sleep(0.001)
  217. f.close()
  218. client.close()
  219. def UDP_recv(udp_port):
  220. BUF_SIZE = 1024
  221. server_addr = ('127.0.0.1', udp_port)
  222. # UDP: socket.SOCK_DGRAM
  223. server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  224. server.bind(server_addr)
  225. count = 0
  226. f = None
  227. filename = ""
  228. while True:
  229. data, addr = server.recvfrom(BUF_SIZE)
  230. if count == 0:
  231. # recive the starting message inculding filename
  232. recv_data_array = data.decode('utf-8').split("%%")
  233. if len(recv_data_array) > 1:
  234. if recv_data_array[0] == "UDP":
  235. filename = recv_data_array[1]
  236. f = open(filename, 'wb')
  237. count += 1
  238. elif str(data) != "b'end'":
  239. try:
  240. f.write(data)
  241. # print(count)
  242. except:
  243. print("[erroe] can not write")
  244. count += 1
  245. else:
  246. f.close()
  247. # print(count)
  248. count = 0
  249. print("\nReceived " + filename.split("_")[1] + " from " + filename.split("_")[0])
  250. if __name__ == '__main__':
  251. # python client.py server_IP server_port client_udp_server_port
  252. if len(sys.argv) > 3:
  253. server_IP = sys.argv[1]
  254. server_port = int(sys.argv[2])
  255. client_udp_server_port = int(sys.argv[3])
  256. udp_recv_t = threading.Thread(target=UDP_recv, args=(client_udp_server_port,)).start()
  257. tcp_start(server_IP, server_port, client_udp_server_port)
  258. else:
  259. print("[error] Usage: python client.py server_IP server_port client_udp_server_port ")
  260. # just for test
  261. # server_IP = "127.0.0.1"
  262. # server_port = 9000
  263. # client_udp_server_port = 7777
  264. # udp_recv_t = threading.Thread(target=UDP_recv, args=(client_udp_server_port,)).start()
  265. # tcp_start(server_IP, server_port, client_udp_server_port)
Server 点击查看代码
  1. # Python 3
  2. # coding: utf-8
  3. from socket import *
  4. import time
  5. import sys
  6. import threading
  7. import traceback
  8. # If true, print debug information
  9. __DEBUG = False
  10. # max number of consecutive failed attempts
  11. MAX_ERR_COUNT = 0
  12. # server IP
  13. serverIP = '127.0.0.1'
  14. # record clients who try to connect to server
  15. client_connect_list = []
  16. # ClientInfo class
  17. # manager client infomation
  18. class ClientInfo():
  19. m_IP=""
  20. m_loginTimestamp = -1
  21. m_preLoginTime = -1
  22. m_username=""
  23. m_UDPServerPort = -1
  24. m_errorCount = 0
  25. def __init__(self, IP):
  26. self.m_IP = IP
  27. def add_logInfo(self, name, timestamp, UDPport):
  28. self.m_loginTimestamp = timestamp
  29. self.m_username = name
  30. self.m_UDPServerPort = UDPport
  31. if self.m_errorCount < MAX_ERR_COUNT:
  32. self.m_preLoginTime = self.m_loginTimestamp
  33. # print("Debug: self.m_errorCount: " + str(self.m_errorCount))
  34. return True
  35. else:
  36. if (int(self.m_loginTimestamp) - int(self.m_preLoginTime) > 30):
  37. self.m_errorCount = 0
  38. self.m_errorCount = self.m_errorCount + 1
  39. return True
  40. else:
  41. return False
  42. # record number_of_consecutive_failed_attempts
  43. def error_password(self):
  44. self.m_errorCount = self.m_errorCount + 1
  45. # check name and password
  46. def check_credential(username, password):
  47. res = False
  48. with open('credentials.txt', 'r') as file:
  49. credential_list = file.readlines()
  50. for credential in credential_list:
  51. name = credential.strip().split(" ")[0]
  52. pwd = credential.strip().split(" ")[1]
  53. if (name==username and pwd == password):
  54. res = True
  55. break
  56. if __DEBUG: print("check_credential: res: " , res)
  57. return res
  58. # Get client infomation by IP
  59. def get_client_from_connect_list(IP):
  60. for c in client_connect_list:
  61. if c.m_IP == IP:
  62. return c
  63. return None
  64. # Add a new client to cse_userlog.txt
  65. def add_user_log(name, timestamp, IP, UDPport):
  66. dt = time.strftime("%d %b %Y %H:%M:%S", time.localtime(int(timestamp)))
  67. address = IP[0]
  68. txt = dt + "; " + name + "; " + address + "; " + str(UDPport)
  69. index = 0
  70. # read old file to get log index
  71. with open('cse_userlog.txt', mode='r', encoding="utf-8") as user_file:
  72. log_list = user_file.readlines()
  73. if log_list:
  74. last_line = log_list[-1]
  75. index = int(last_line.strip().split("; ")[0])
  76. else:
  77. index = 0
  78. # write new log in file
  79. with open('cse_userlog.txt', mode='a+', encoding="utf-8") as user_file:
  80. msg = str(index+1) + '; ' + txt
  81. user_file.write(msg + "\n")
  82. # OUT: delete a client from cse_userlog.txt and adjust other client's index
  83. def del_user_log(name):
  84. new_log_list=[]
  85. index = 1
  86. with open('cse_userlog.txt', mode='r', encoding="utf-8") as user_file:
  87. log_list = user_file.readlines()
  88. for log in log_list:
  89. log_arr = log.split("; ")
  90. log_txt = log_arr[1:]
  91. log_prot = log_arr[4]
  92. log_addr = log_arr[3]
  93. log_name = log_arr[2]
  94. if log_name == name:
  95. if __DEBUG: print("Debug: find same IP need to delete: " + str(log_arr[0]))
  96. pass
  97. else:
  98. txt = "; ".join(i for i in log_txt)
  99. msg = str(index) + "; " + txt
  100. index = index + 1
  101. new_log_list.append(msg)
  102. with open('cse_userlog.txt', mode='w', encoding="utf-8") as user_file:
  103. user_file.writelines(new_log_list)
  104. # ATU: read other user log from cse_userlog.txt and return
  105. def show_user_log_exclude_self(name):
  106. new_log_list=[]
  107. with open('cse_userlog.txt', mode='r', encoding="utf-8") as user_file:
  108. log_list = user_file.readlines()
  109. for log in log_list:
  110. log_arr = log.split("; ")
  111. log_txt = log_arr[1:]
  112. log_name = log_arr[2]
  113. if log_name == name :
  114. if __DEBUG: print("Debug: find same name no need to show: " + str(log_arr[0]))
  115. pass
  116. else:
  117. txt = "; ".join(i for i in log_txt)
  118. msg = txt
  119. new_log_list.append(msg)
  120. return new_log_list
  121. # MSG: When someone posts a new message, add it to the messagelog.txt
  122. def add_msg_log(name, timestamp, txt):
  123. dt = time.strftime("%d %b %Y %H:%M:%S", time.localtime(int(timestamp)))
  124. log_txt = dt + "; " + name + "; " + txt
  125. index = 0
  126. with open('messagelog.txt', mode='r', encoding="utf-8") as msg_file:
  127. log_list = msg_file.readlines()
  128. if log_list:
  129. last_line = log_list[-1]
  130. index = int(last_line.strip().split("; ")[0])
  131. else:
  132. index = 0
  133. with open('messagelog.txt', mode='a+', encoding="utf-8") as msg_file:
  134. msg = str(index + 1) + '; ' + log_txt + '; ' + 'no'
  135. msg_file.write(msg + "\n")
  136. return index + 1
  137. # convert formatted date time to timestamp
  138. def dt_to_timestamp(dt):
  139. timeArray = time.strptime(dt, "%d %b %Y %H:%M:%S")
  140. timeStamp = int(time.mktime(timeArray))
  141. return timeStamp
  142. # RDM: read message log by different time
  143. def read_msg_log(timestamp):
  144. new_log_list=[]
  145. with open('messagelog.txt', mode='r', encoding="utf-8") as msg_file:
  146. log_list = msg_file.readlines()
  147. for log in log_list:
  148. log_arr = log.split("; ")
  149. log_dt = log_arr[1]
  150. log_timestamp = dt_to_timestamp(log_dt)
  151. log_name = log_arr[2]
  152. if log_timestamp < timestamp:
  153. pass
  154. else:
  155. new_log_list.append(log)
  156. return new_log_list
  157. # DLT: delete a client's own message by time
  158. def del_msg_log(name, del_index, del_dt):
  159. del_res = False
  160. del_txt = ""
  161. new_log_list=[]
  162. index = 1
  163. with open('messagelog.txt', mode='r', encoding="utf-8") as msg_file:
  164. log_list = msg_file.readlines()
  165. for log in log_list:
  166. log_arr = log.split("; ")
  167. log_txt = log_arr[1:]
  168. log_dt = log_arr[1]
  169. log_name = log_arr[2]
  170. if log_dt == del_dt and log_name == name and index == del_index:
  171. del_res = True
  172. del_txt = log_arr[3]
  173. if __DEBUG: print("Debug: find same name and index and time need to delete: " + str(log_arr[0]))
  174. pass
  175. else:
  176. txt = "; ".join(i for i in log_txt)
  177. msg = str(index) + "; " + txt
  178. index = index + 1
  179. new_log_list.append(msg)
  180. with open('messagelog.txt', mode='w', encoding="utf-8") as msg_file:
  181. msg_file.writelines(new_log_list)
  182. return del_res, del_txt
  183. # EDT: edit a client's own message by time
  184. def edit_msg_log(name, edit_index, edit_dt, edit_txt):
  185. edit_res = False
  186. new_log_list=[]
  187. edit_time = ''
  188. with open('messagelog.txt', mode='r', encoding="utf-8") as msg_file:
  189. log_list = msg_file.readlines()
  190. for log in log_list:
  191. log_arr = log.split("; ")
  192. log_index = log_arr[0]
  193. log_txt = log_arr[3]
  194. log_dt = log_arr[1]
  195. log_name = log_arr[2]
  196. if log_dt == edit_dt and log_name == name and log_index == str(edit_index):
  197. edit_res = True
  198. edit_time = time.strftime("%d %b %Y %H:%M:%S", time.localtime(int(time.time())))
  199. log_arr[3] = edit_txt
  200. log_arr[1] = edit_time
  201. log_arr[4] = "yes\n"
  202. if __DEBUG: print("Debug: find same name and index and time need to edit: " + str(log_arr[0]))
  203. log = "; ".join(log_arr)
  204. new_log_list.append(log)
  205. if __DEBUG: print("Debug: new log ", log)
  206. else:
  207. new_log_list.append(log)
  208. with open('messagelog.txt', mode='w', encoding="utf-8") as msg_file:
  209. msg_file.writelines(new_log_list)
  210. return edit_res, edit_time
  211. # parse the msg from client and make different responses based on different client commands
  212. def reponse_to_client(clientSocket, IP, recv_msg):
  213. socket_status = True
  214. send_msg = ""
  215. recv_msg_list = []
  216. recv_msg_list = recv_msg.split("%%")
  217. pwd_status = True
  218. if len(recv_msg_list) != 0:
  219. flag = recv_msg_list[0]
  220. else:
  221. print("[error] parse error")
  222. pass
  223. if __DEBUG: print("Debug: flag is " + flag)
  224. client = get_client_from_connect_list(IP)
  225. # response to login
  226. if (flag == "LOGIN"):
  227. name = recv_msg_list[1]
  228. pwd = recv_msg_list[2]
  229. UDPPort = recv_msg_list[3]
  230. pwd_status = check_credential(name, pwd)
  231. # if wrong name and password, number of consecutive failed attempts adds 1
  232. if not pwd_status:
  233. client.error_password()
  234. if client is None:
  235. client = ClientInfo(IP)
  236. client_connect_list.append(client)
  237. # save user information
  238. add_status = client.add_logInfo(name, time.time(), UDPPort)
  239. if add_status == True:
  240. if pwd_status == False:
  241. TYPE = "1"
  242. if client.m_errorCount == MAX_ERR_COUNT:
  243. DATA = "Invalid Password. Your account has been blocked. Please try again later"
  244. else:
  245. DATA = "Invalid Password. Please try again!"
  246. elif pwd_status == True:
  247. TYPE = "0"
  248. DATA = "Log in sucessfully!"
  249. add_user_log(name, client.m_loginTimestamp, IP, client.m_UDPServerPort)
  250. server_output = client.m_username + " log in sucessfully"
  251. print(server_output)
  252. else:
  253. TYPE = "2"
  254. DATA = "Your account is blocked due to multiple login failures. Please try again later"
  255. FLAG = flag
  256. send_msg = FLAG + "%%" + TYPE + "%%" + DATA
  257. # response to "MSG" command
  258. elif (flag == "MSG"):
  259. txt = recv_msg_list[1]
  260. if __DEBUG: print("Debug: " + txt)
  261. timestamp = time.time()
  262. msg_index = add_msg_log(client.m_username, timestamp, txt)
  263. dt = time.strftime("%d %b %Y %H:%M:%S", time.localtime(int(timestamp)))
  264. FLAG = flag
  265. DATA = "Message #" + str(msg_index) + " posted at " + dt
  266. send_msg = FLAG + "%%" + DATA
  267. server_output = client.m_username + " posted MSG #" + str(msg_index) + " \"" + txt + "\" at " + dt + "."
  268. print(server_output)
  269. # response to "RDM" command
  270. elif (flag == "RDM"):
  271. FLAG = flag
  272. DATA = ""
  273. dt = recv_msg_list[1]
  274. try:
  275. timestamp = dt_to_timestamp(dt)
  276. except Exception as e:
  277. print(e)
  278. send_msg = FLAG + "%%" + "unknown time, please check time format"
  279. clientSocket.send(send_msg.encode('utf-8'))
  280. return
  281. log_list = read_msg_log(timestamp)
  282. if len(log_list) == 0:
  283. DATA = "no new message"
  284. else:
  285. # print(log_list)
  286. for log in log_list:
  287. log_arr = log.split("; ")
  288. log_edit_status = log_arr[4]
  289. log_index = log_arr[0]
  290. log_name = log_arr[2]
  291. log_txt = log_arr[3]
  292. log_dt = log_arr[1]
  293. if log_edit_status.strip() == "no":
  294. log_edit_status = "posted"
  295. elif log_edit_status.strip() == "yes":
  296. log_edit_status = "edited"
  297. m = "#" + log_index + " " + log_name + ", " + log_txt + ", " + log_edit_status + " at " + log_dt + "%%"
  298. DATA = DATA + m
  299. send_msg = FLAG + "%%" + DATA
  300. #Yoda issued RDM command
  301. server_output = client.m_username + " issued RDM command."
  302. print(server_output)
  303. # response to "EDT" command
  304. elif (flag == "EDT"):
  305. FLAG = flag
  306. edit_index = int(recv_msg_list[1])
  307. edit_dt = recv_msg_list[2]
  308. edit_txt = recv_msg_list[3]
  309. edit_res, edit_time = edit_msg_log(client.m_username, edit_index, edit_dt, edit_txt)
  310. if edit_res:
  311. TYPE = "0" # del success
  312. DATA = "Message #" + str(edit_index) + " edited at " + edit_time + "."
  313. server_output = client.m_username + " edited MSG #" + str(edit_index) + " \"" + edit_txt + "\" at " + edit_time + "."
  314. print(server_output)
  315. else:
  316. TYPE = "1" # del fail
  317. DATA = "Edit message fail, can not find such message"
  318. server_output = client.m_username + " " + DATA
  319. print(server_output)
  320. send_msg = FLAG + "%%" + TYPE + "%%" + DATA
  321. pass
  322. # response to "DLT" command
  323. elif (flag == "DLT"):
  324. FLAG = flag
  325. del_index = int(recv_msg_list[1])
  326. del_dt = recv_msg_list[2]
  327. del_res, del_txt = del_msg_log(client.m_username, del_index, del_dt)
  328. del_time = time.strftime("%d %b %Y %H:%M:%S", time.localtime(int(time.time())))
  329. if del_res:
  330. TYPE = "0" # del success
  331. DATA = "Message #" + str(del_index) + " deleted at " + del_time + "."
  332. server_output = client.m_username + " deleted MSG #" + str(
  333. del_index) + " \"" + del_txt + "\" at " + del_time + "."
  334. print(server_output)
  335. else:
  336. TYPE = "1" # del fail
  337. DATA = "Delete message fail, can not find such message"
  338. server_output = client.m_username + " " + DATA
  339. print(server_output)
  340. send_msg = FLAG + "%%" + TYPE + "%%" + DATA
  341. # response to "ATU" command
  342. elif (flag == "ATU"):
  343. FLAG = flag
  344. DATA = ""
  345. user_list = show_user_log_exclude_self(client.m_username)
  346. NUM = len(user_list)
  347. if len(user_list) == 0:
  348. DATA = "no other active user"
  349. else:
  350. for user in user_list:
  351. user_arr = user.split("; ")
  352. user_dt = user_arr[0]
  353. user_name = user_arr[1]
  354. user_address = user_arr[2]
  355. user_port = user_arr[3]
  356. txt = user_name + ", " + user_address + ", " + user_port.strip() + ", active since " + user_dt + "."
  357. DATA = DATA + txt + '%%'
  358. send_msg = FLAG + "%%" + str(NUM) + "%%" + DATA
  359. server_output = client.m_username + " issued ATU command."
  360. print(server_output)
  361. # response to "OUT" command
  362. elif (flag == "OUT"):
  363. del_user_log(client.m_username)
  364. client = get_client_from_connect_list(IP)
  365. FLAG = flag
  366. send_msg = FLAG + "%%" + "Bye, " + client.m_username + "!"
  367. socket_status = False
  368. server_output = client.m_username + " logout"
  369. print(server_output)
  370. if send_msg != "":
  371. clientSocket.send(send_msg.encode('utf-8'))
  372. if not socket_status:
  373. clientSocket.close()
  374. # Try to recvice msg from client
  375. def read_client(socket, IP):
  376. try:
  377. return socket.recv(2048).decode('utf-8')
  378. except:
  379. # if exception, indicating that the connection failed, the client is deleted
  380. print(str(IP) + ' Left!')
  381. # Always wait for a message from the client
  382. def recv_handler(socket, clientAddress):
  383. try:
  384. while True:
  385. content = read_client(socket, clientAddress)
  386. if content is None:
  387. break
  388. else:
  389. if __DEBUG: print(str(clientAddress) + " received: " + content)
  390. reponse_to_client(socket, clientAddress, content)
  391. except Exception as e:
  392. # raise Exception
  393. print("[error]: ", e)
  394. exstr = traceback.format_exc()
  395. if __DEBUG: print("debug: " + exstr)
  396. pass
  397. def start(server_port):
  398. serverSocket = socket(AF_INET, SOCK_STREAM)
  399. serverSocket.bind((serverIP, server_port))
  400. serverSocket.listen(1)
  401. print("Server start ... ")
  402. print("waiting client ...")
  403. while True:
  404. clientSocket, clientAddress = serverSocket.accept()
  405. # record each client when server accept successfully
  406. client = ClientInfo(clientAddress)
  407. client_connect_list.append(client)
  408. if __DEBUG: print(str(clientAddress) + ' is trying to connect!')
  409. # start recv_handler for each client
  410. threading.Thread(target=recv_handler, args=(clientSocket, clientAddress)).start()
  411. if __name__ == '__main__':
  412. # create messagelog.txt
  413. msg_file = open('messagelog.txt', 'w')
  414. msg_file.close()
  415. # create cse_userlog.txt
  416. user_file = open('cse_userlog.txt', 'w')
  417. user_file.close()
  418. # python server.py server_port number_of_consecutive_failed_attempts
  419. if len(sys.argv) > 2:
  420. server_port = int(sys.argv[1])
  421. MAX_ERR_COUNT = int(sys.argv[2])
  422. start(server_port)
  423. else:
  424. print("[error] Usage: python server.py server_port number_of_consecutive_failed_attempts ")
  425. # just for test
  426. # server_port = 9000
  427. # MAX_ERR_COUNT = 6
  428. # start(server_port)

Python3 网络通信 网络聊天室 文件传输的更多相关文章

  1. android asmack 注册 登陆 聊天 多人聊天室 文件传输

    XMPP协议简介 XMPP协议(Extensible Messaging and PresenceProtocol,可扩展消息处理现场协议)是一种基于XML的协议,目的是为了解决及时通信标准而提出来的 ...

  2. php websocket-网页实时聊天之PHP实现websocket(ajax长轮询和websocket都可以时间网络聊天室)

    php websocket-网页实时聊天之PHP实现websocket(ajax长轮询和websocket都可以时间网络聊天室) 一.总结 1.ajax长轮询和websocket都可以时间网络聊天室 ...

  3. 基于Linux的TCP网络聊天室

    1.实验项目名称:基于Linux的TCP网络聊天室 2.实验目的:通过TCP完成多用户群聊和私聊功能. 3.实验过程: 通过socket建立用户连接并传送用户输入的信息,分别来写客户端和服务器端,利用 ...

  4. Qt NetWork即时通讯网络聊天室(基于TCP)

    本文使用QT的网络模块来创建一个网络聊天室程序,主要包括以下功能: 1.基于TCP的可靠连接(QTcpServer.QTcpSocket) 2.一个服务器,多个客户端 3.服务器接收到某个客户端的请求 ...

  5. java基于P2P的聊天和文件传输实例

    用java的NIO技术编写的 1. 支持聊天功能 2. 拖拽文件能够实现文件传输功能.也能够是目录 3. 启动时能够选择server端或client端启动 4. 本人原创.学习NIO和java的网络通 ...

  6. Java NIO示例:多人网络聊天室

    一个多客户端聊天室,支持多客户端聊天,有如下功能: 功能1: 客户端通过Java NIO连接到服务端,支持多客户端的连接 功能2:客户端初次连接时,服务端提示输入昵称,如果昵称已经有人使用,提示重新输 ...

  7. 使用socket搭建一个网络聊天室

    #服务器端import socket import threading #创建一个TCP端 sock = socket.socket(socket.AF_INET, socket.SOCK_STREA ...

  8. Java WebSocket实现网络聊天室(群聊+私聊)

    1.简单说明 在网上看到一份比较nice的基于webSocket网页聊天项目,准备看看学习学习,如是有了这篇文章!原博主博客:http://blog.csdn.net/Amayadream/artic ...

  9. Netty网络聊天室之会话管理

    写过web的同学们应该对Session这个东西很熟悉.浏览器第一次与服务器建立连接的时候,服务器就会自动为之分配一个Session.Session可以用来判断用户是否经过登录验证,也可以保存用户的各种 ...

随机推荐

  1. Learning ROS: rostopic pub yaml demo

    官方Tutorials中例程的等效命令: rostopic pub -1 /turtle1/cmd_vel geometry_msgs/Twist -- '{linear:[2.0, 0.0, 0.0 ...

  2. css写法

    id选择器 > 类选择器 > 标签选择器 @charset "utf-8"; charset=utf-8   表示当前文档的字符集是采用utf-8的字符,也就是我们常说 ...

  3. 快速构建CLI程序并发布到PyPi

    构造一个简单的CLI程序 typer 这个从去年就被各种营销号吹成Web框架的 第三方库, 与 FastAPI 同出一人之手,它不是Web框架,它是一个用来构建CLI程序的库,我们就简单搞个例子 # ...

  4. K8s 系列(四) - 浅谈 Informer

    1. 概述 进入 K8s 的世界,会发现有很多的 Controller,它们都是为了完成某类资源(如 pod 是通过 DeploymentController, ReplicaSetControlle ...

  5. unity渲染篇:烘焙模型贴图

    今天要来做一件有趣的事情,那就是把一个模型数据烘焙到贴图上! 什么意思?就是下面酱紫,把这只小喵从第一张图拍扁,变成第二张图的样子(似乎有点残忍~) 可能你经常会从美术那边听到"烘焙光照贴图 ...

  6. WebDriverAgent重签名爬坑记

    接上一篇博文,已经配置好了Xcode环境,那接下来要完成的就是重签名WebDriverAgent.在讲重签名之前,我们还是先来了解下WebDriverAgent,熟悉的朋友,可以直接跳过. WebDr ...

  7. 【第十九篇】- Maven NetBeans之Spring Cloud直播商城 b2b2c电子商务技术总结

    Maven NetBeans NetBeans 6.7 及更新的版本已经内置了 Maven.对于以前的版本,可在插件管理中心获取 Maven 插件.此例中我们使用的是 NetBeans 6.9. 关于 ...

  8. 【第六篇】- Maven 仓库之Spring Cloud直播商城 b2b2c电子商务技术总结

    Maven 仓库 在 Maven 的术语中,仓库是一个位置(place). Maven 仓库是项目中依赖的第三方库,这个库所在的位置叫做仓库. 在 Maven 中,任何一个依赖.插件或者项目构建的输出 ...

  9. 生产环境部署高可用Rancher

    环境准备: IP hostname role 192.168.200.150 nginx LB 192.168.200.151 master01-151 docker-ce/rke/helm/kube ...

  10. 计算机网络 -- TCP/IP

    画图标准 OSI七层模型 7.应用层 作用:为用户提供软件/接口/界面 interface 协议:OICQ.HTTP.HTTPS.BT/P2P 6.表示层 作用:用于对用户数据进行数据呈现.(数据格式 ...