Spaces:
Paused
Paused
File size: 4,236 Bytes
b5e065e | 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 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | import socket
import threading
import queue
import json # json.dumps(some)打包 json.loads(some)解包
import os
import os.path
import sys
ipconfig = input("请输入ip地址(推荐127.0.0.1)")
PORTconfig = input("请输入端口(随便编一个4位数,注意在windows系统中端口不能重复)")
port = int(PORTconfig)
IP = ipconfig
PORT = port # 端口
messages = queue.Queue()
users = [] # 0:userName 1:connection
lock = threading.Lock()
def onlines(): # 统计当前在线人员
online = []
for i in range(len(users)):
online.append(users[i][0])
return online
class ChatServer(threading.Thread):
global users, que, lock
def __init__(self): # 构造函数
threading.Thread.__init__(self)
self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
os.chdir(sys.path[0])
# 接受来自客户端的用户名,如果用户名为空,使用用户的IP与端口作为用户名。如果用户名出现重复,则在出现的用户名依此加上后缀“2”、“3”、“4”……
def receive(self, conn, addr): # 接收消息
user = conn.recv(1024) # 用户名称
user = user.decode()
if user == '用户名不存在':
user = addr[0] + ':' + str(addr[1])
tag = 1
temp = user
for i in range(len(users)): # 检验重名,则在重名用户后加数字
if users[i][0] == user:
tag = tag + 1
user = temp + str(tag)
users.append((user, conn))
USERS = onlines()
self.Load(USERS,addr)
# 在获取用户名后便会不断地接受用户端发来的消息(即聊天内容),结束后关闭连接。
try:
while True:
message = conn.recv(1024) # 发送消息
message = message.decode()
message = user + ':' + message
self.Load(message,addr)
conn.close()
# 如果用户断开连接,将该用户从用户列表中删除,然后更新用户列表。
except:
j = 0 # 用户断开连接
for man in users:
if man[0] == user:
users.pop(j) # 服务器段删除退出的用户
break
j = j+1
USERS = onlines()
self.Load(USERS,addr)
conn.close()
# 将地址与数据(需发送给客户端)存入messages队列。
def Load(self, data, addr):
lock.acquire()
try:
messages.put((addr, data))
finally:
lock.release()
# 服务端在接受到数据后,会对其进行一些处理然后发送给客户端,如下图,对于聊天内容,服务端直接发送给客户端,而对于用户列表,便由json.dumps处理后发送。
def sendData(self): # 发送数据
while True:
if not messages.empty():
message = messages.get()
if isinstance(message[1], str):
for i in range(len(users)):
data = ' ' + message[1]
users[i][1].send(data.encode())
print(data)
print('\n')
if isinstance(message[1], list):
data = json.dumps(message[1])
for i in range(len(users)):
try:
users[i][1].send(data.encode())
except:
pass
def run(self):
self.s.bind((IP,PORT))
self.s.listen(5)
q = threading.Thread(target=self.sendData)
q.start()
while True:
conn, addr = self.s.accept()
t = threading.Thread(target=self.receive, args=(conn, addr))
t.start()
self.s.close()
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def greet_json():
return {"Sever is running 服务器已启用,协议:TCP "}
if __name__ == '__main__':
cserver = ChatServer()
print("服务器启动完毕,请使用客户端进行连线")
cserver.start() |