我的环境:windows10&;python 3.6
图像解释
1.服务器在左侧窗口运行,客户端A在右侧窗口运行,客户端B在底部窗口运行。
2.具体操作是:客户端B发送“a B c d e”,客户端a接收“a”。客户端A发送“A b c e d”,客户端b接收“[某些信息..]A\n[某些信息..]A”
3.我们可以从图中了解到:当客户端在其他客户端发送任何消息之前发送多条消息时,其他客户端将只接收客户端A发送的第一条消息或接收重复消息
最后,很抱歉我对套接字和线程理解不好,解释不好。谢谢你的帮助
code for clinet:
import socket
import time
import threading
SERVER_HOST = "" # server ip
LOCAL_HOST = "10.124.18.206"
HOST = LOCAL_HOST
HEADER = 64
PORT = 42366
CHECK_CLIENT = "!CHECK"
FORMAT = "utf-8"
DISCONNECT_MESSAGE = "!DISCONNECT"
KEEP_MESSAGE = "KEEP"
TIMEOUT = 50
def gettimestamp():
return time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())
def send(msg):
message = msg.encode(FORMAT)
msg_length = len(message)
send_length = str(msg_length).encode(FORMAT)
send_length += b' ' * (HEADER-len(send_length))
client.send(send_length)
client.send(message)
def recv():
message = client.recv(HEADER)
msg_length = len(message)
message = message.decode(FORMAT)
data = client.recv(msg_length).decode(FORMAT)
return data
def listen():
while True:
data = recv()
if data:
print(f"[MESSAGE {gettimestamp()}] {data}" )
else:
break
def start():
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
print(f"[STARTING] Connecting to {HOST}:{PORT}")
client.connect((HOST,PORT))
send(CHECK_CLIENT)
client_num = recv()
print(f"There are {client_num} people in the chat.")
print("Let's chat!")
connected = True
listen_th = threading.Thread(target=listen,args=())
listen_th.daemon = True
listen_th.start()
while connected:
time.sleep(0.3)
data = input("[INPUT] ")
try:
send(data)
except ConnectionAbortedError as e:
connected = False
if data == DISCONNECT_MESSAGE:
connected = False
print(f"[DISCONNECT {gettimestamp()}] {HOST}:{PORT}")
client.close()
if __name__ == "__main__":
start()
code for server
# -*- coding: utf-8 -*-
import socket
import threading
import time
SERVER_HOST = "" # server ip
LOCAL_HOST = "10.124.18.206"
HOST = LOCAL_HOST
PORT = 42366
CHECK_CLIENT = "!CHECK"
DISCONNECT_MESSAGE = "!DISCONNECT"
HEADER = 64
FORMAT = "utf-8"
TIMEOUT = 60
clients = []
def gettimestamp():
return time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())
def send(conn,msg):
try:
message = msg.encode(FORMAT)
msg_length = len(message)
send_length = str(msg_length).encode(FORMAT)
send_length += b' ' * (HEADER-len(send_length))
conn.send(send_length)
conn.send(message)
except OSError as e:
print(f"{e} in line 33")
clients.remove(conn)
def update_chat(msg,conn):
global clients
temp = []
for client in clients:
flag = 1
if client != conn:
try:
send(client,msg)
except BrokenPipeError as e:
print(f"{e} in line 45")
flag = 0
continue
if flag == 1:
temp.append(conn)
clients = temp
def handle_client(addr,conn):
print(f"[NEW CONNECTION {gettimestamp()}] {addr} connected.")
print(f"[ACTIVE CONNECTIONS {gettimestamp()}] {threading.activeCount()-1}")
connected = True
clients.append(conn)
while connected:
try:
conn.settimeout(TIMEOUT)
msg_length = conn.recv(HEADER).decode(FORMAT)
conn.settimeout(None)
if msg_length:
msg_length = int(msg_length)
try:
msg = conn.recv(msg_length).decode(FORMAT)
except ConnectionResetError as e:
print(f"{e} in line 67")
connected = False
if msg == DISCONNECT_MESSAGE:
connected = False
clients.remove(conn)
elif msg == CHECK_CLIENT:
client_num = threading.activeCount()-1
send(conn,str(client_num))
else:
update_chat(f"{msg}",conn)
print(f"[{addr[0]+str(addr[1])} {gettimestamp()}] {msg}")
except ConnectionResetError as e:
print(f"{e} in line 81")
connected = False
except ConnectionAbortedError as e:
print(f"{e} in line 84")
continue
except socket.timeout as e:
connected = False
print(f"[DISCONNECTED {gettimestamp()}] {addr}")
conn.close()
def start():
print("[STARTING] Server is starting...")
server = socket.socket()
print(f"[BIDING] Binding address {HOST}:{PORT}")
server.bind((HOST,PORT))
server.listen()
print(f"[LISTENING {gettimestamp()}] Server is listening on {HOST}:{PORT}")
while True:
conn,addr = server.accept()
thread = threading.Thread(target=handle_client,args=(addr,conn))
thread.daemon = True
thread.start()
if __name__ == "__main__":
start()
这将接收到
msg_length
字节。您需要确保准确地接收字节。您可能希望编写一个receive all函数,反复调用recv
,直到收到所需的字节数相关问题 更多 >
编程相关推荐