【发布时间】:2020-09-24 06:37:31
【问题描述】:
我正在使用 python 创建一个简单的聊天室服务器,当我使用它发送数据时,我没有收到它。该代码一直有效,直到我使用函数和类将其分开。我这样做是为了添加 UI 会更简单
这是我的服务器端代码:
import socket
import select
from tkinter import *
import threading
HEADER_LENGTH = 10
IP = socket.gethostbyname('0.0.0.0')
PORT = 1234
class ServerNoGui():
def __init__(self):
self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.server_socket.bind((IP, PORT))
self.server_socket.listen()
self.sockets_list = [self.server_socket]
self.clients = {}
print("server started")
print("Starting thread sub-proccesses...")
acceptLoop = threading.Thread(target=self.acceptUsers)
acceptLoop.start()
recieveLoop = threading.Thread(target=self.manageDataSending)
recieveLoop.start()
print("sub-proccesses started!")
def recieve_message(self, client_socket):
message_header = client_socket.recv(HEADER_LENGTH)
if not len(message_header):
return False
message_length = int(float(message_header.decode('utf-8').strip()))
return {'header': message_header, 'data': client_socket.recv(message_length)}
def acceptUsers(self):
read_sockets, _x_, exception_sockets = select.select(self.sockets_list, [], self.sockets_list)
for notified_socket in read_sockets:
if notified_socket == self.server_socket:
client_socket, client_address = self.server_socket.accept()
print("accepted")
user = self.recieve_message(client_socket)
#print(user)
print("Recieved")
if(not user):
continue
self.sockets_list.append(client_socket)
print("added to list")
self.clients[client_socket] = user
print("created user")
print(f"Accepted connection from {client_address[0]}{client_address[1]} username: {user['data'].decode('utf-8')}")
def manageDataSending(self):
while True:
read_sockets, _x_, exception_sockets = select.select(self.sockets_list, [], self.sockets_list)
print("point")
for notified_socket in read_sockets:
if notified_socket == self.server_socket:
print("point 0")
self.acceptUsers()
else:
print("point 1")
message = self.recieve_message(notified_socket)
if(message is False):
print(f"Closed connection from {self.clients[notified_socket]['data'].decode('utf-8')}")
self.sockets_list.remove(notified_socket)
del self.clients[notified_socket]
continue
else:
user = self.clients[notified_socket]
type_, data = message['data'].decode("utf-8").split("$")
if(type_ == "message"):
print(f"Recieved Message from {user['data'].decode('utf-8')} : {message['data'].decode('utf-8')} of type {type_}")
for client_socket in self.clients:
if client_socket != notified_socket:
client_socket.send(user['header'] + user['data'] + message['header'] + message['data'])
for notified_socket in exception_sockets:
sockets_list.remove(notified_socket)
del clients[notified_socket]
print(f"Closed connection from {clients[notified_socket]['data'].decode('utf-8')}")
class serverGUI():
def __init__():
window = Tk()
window.title(f"Chatt.py HOSTING SERVER (IP : {IP} \\\\ HOST : {HOST})")
def createWidgets(self):
return False
def log(self, data):
return False
def loop(self):
window.mainloop()
serverBackend = ServerNoGui()
这是客户
import socket
import select
import errno
import sys
HEADER_LENGTH = 10
IP = socket.gethostbyname("0.0.0.0")#'192.168.0.40'
PORT = 1234
my_username = input("Username: ")
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect((IP, PORT))
client_socket.setblocking(False)
username = my_username.encode("utf-8");
username_header = f"{len(username):<{HEADER_LENGTH}}".encode("utf-8")
client_socket.send(username_header + username)
while True:
messageInput = input(f"Me({my_username}) > ")
message = f"message${messageInput}"
if(message):
message = message.encode("utf-8")
message_header = f"{len(message):<{HEADER_LENGTH}}".encode("utf-8")
client_socket.send(message_header + message)
print(f"sent {message_header} : {message}")
try:
while True:
username_header = client_socket.recv(HEADER_LENGTH)
if(not len(username_header)):
print("connection closed by server")
sys.exit()
username_lenght = int(username_header.decode("utf-8").strip())
username = client_socket.recv(username_lenght).decode("utf-8")
message_header = client_socket.recv(HEADER_LENGTH)
message_length = int(message_header.decode("utf-8").strip())
messageRaw = client_socket.recv(message_length).decode("utf-8")
type_, message = messageRaw.split("$")
if(type_ == message):
print(f"{username} >> {message}")
except IOError as e:
if(e.errno != errno.EAGAIN and e.errno != errno.EWOULDBLOCK):
print("READ ERR",str(e))
sys.exit()
continue
except Exception as e:
print("Error".str(e))
sys.exit()
我决定尝试两个客户端我得到以下输出 服务器:
server started
Starting thread sub-proccesses...
sub-proccesses started!
point
point 0
accepted
Recieved
added to list
created user
Accepted connection from 127.0.0.160338 username: test1
point
point 0
accepted
Recieved
added to list
created user
Accepted connection from 127.0.0.160340 username: test2
point
point 1
Recieved Message from test2 : message$hello of type message
point
point 1
Recieved Message from test1 : message$ of type message
point
point 1
Recieved Message from test1 : message$hello of type message
客户端1:
Username: test1
Me(test1) >
sent b'8 ' : b'message$'
Me(test1) > hello
sent b'13 ' : b'message$hello'
客户端2:
Username: test2
Me(test2) > hello
sent b'13 ' : b'message$hello'
如您所见,消息由服务器发送和接收,但未显示(我不傻,我按了几次回车键)。
【问题讨论】:
标签: python python-3.x sockets server