在python中使用socket编程创建一个简易聊天室的数据传输问题?

题目描述

在python中使用socket编程创建一个简易聊天室的数据传输问题?

题目来源及自己的思路

抱歉,应该是基于UDP协议

创建客户端和服务端两端代码,实现收发信息代码完善后复制客户端代码副本即可

相关代码

粘贴代码文本(请勿用截图)
服务端代码如下

# encoding=utf-8

import socket

import time

# 服务器的功能:收到信息后转发

def recv_send(server_ip, server_port):

# 创建套接字

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 指明网络层和传输层的协议

s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

# 绑定服务器地址

s.bind((server_ip, server_port))

user_dict = {} # 保存用户名和其客户端地址

# 开始接收和发送数据

while True:

# 接收数据

recv_data, cli_addr = s.recvfrom(1024)

# 接收数据后解码并保存变量

recv_data = recv_data.decode('utf-8')

# 提取用户名和发送的信息并指定分割符

present_user, real_info = recv_data.split(':')

# if present_user in real_info and "欢迎" in real_info:

# user_dict[present_user] = cli_addr

# # 向其他客户端发送一个欢迎当前用户的信息

# for user, addr in user_dict.items():

# if user != present_user:

# send_data = f"server:欢迎{present_user}进入聊天室..."

# s.sendto(send_data.encode('utf-8'), addr)

# else:

# for user, addr in user_dict.items():

# if user != present_user:

# s.sendto(real_info.encode('utf-8'), addr)

# 判断用户是否是第一次进入聊天室

if present_user in real_info and "欢迎" in real_info:

user_dict[present_user] = cli_addr

# 向其他客户端发送一个欢迎当前用户的信息

send_data = f"server:欢迎{present_user}进入聊天室..."

else:

send_data = recv_data

# 判断用户是否退出

if real_info == 'exit': # 则从用户字典删除该用户

del user_dict[present_user]

send_data = f"server:{present_user}退出了聊天室..."

for user, addr in user_dict.items():

if user != present_user:

s.sendto(real_info.encode('utf-8'), addr)

# 显示收到的信息

print(f"{present_user} {time.strftime('%Y-%m-%d %H:%M:%S')}")

print(f" {real_info}")

def main():

server_ip = '127.0.0.1'

server_port = 6666

recv_send(server_ip, server_port)

if __name__ == '__main__':

main()

客户端代码如下

# encoding=utf-8

import socket

import threading

import time

# 发送数据函数

def send(socket_obj, server_addr, client_user):

while True:

send_data = input("服务器已启动:")

send_data = f"{client_user}:{send_data}"

socket_obj.sendto(send_data.encode('utf-8'), server_addr)

if send_data == 'exit':

break

# 接收数据函数

def recv(socket_obj):

while True:

try:

recv_data, addr = socket_obj.recvfrom(1024)

except:

break

recv_data, addr = socket_obj.recvfrom(1024)

recv_data = recv_data.decode('utf-8')

user_name, real_data = recv_data.split(":")

# 显示收到的信息

print(f"{user_name} {time.strftime('%Y-%m-%d %H:%M:%S')}")

print(f" {real_data}")

def main():

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 指明网络层和传输层的协议

s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

# 设置服务器ip和端口号

sever_ip = '127.0.0.1'

server_port = 6666

server_addr = (sever_ip, server_port)

# 给客户端设置用户名

user_name = '张三'

# 第一次进入聊天室,发送一个欢迎信息,让服务器知道用户的地址

send_info = f"{user_name}:欢迎{user_name}进入聊天室..."

s.sendto(send_info.encode('utf-8'), server_addr)

# (1)创建两个线程,一个发送数据,一个接收数据

a_send = threading.Thread(target=send, args=(s, server_addr, user_name))

a_recv = threading.Thread(target=recv, args=(s,))

# 启动线程

a_send.start()

a_recv.start()

a_send.join() # 等待发送线程结束

# 关闭套接字对象

s.close()

if __name__ == '__main__':

main()

你期待的结果是什么?实际看到的错误信息又是什么?

实际错误信息如下
在python中使用socket编程创建一个简易聊天室的数据传输问题?
但问题是,若两个客户端为同一user_name此时可以正常通信如下图,但两个客户端若为不同user_name则某一客户端会出现第一张图的错误,恳请大佬解惑!
在python中使用socket编程创建一个简易聊天室的数据传输问题?


回答:

俩问题。

  1. 发送时数据格式问题
        for user, addr in user_dict.items():

if user != present_user:

# FIXME: 这块应该是 --> "用户名:消息" <--

s.sendto(real_info.encode('utf-8'), addr)

  1. 接收数据时
# 接收数据函数

def recv(socket_obj):

while True:

try:

# FIXME: 这里接收的数据直接忽略了?

recv_data, addr = socket_obj.recvfrom(1024)

except:

break

# 这边接收的话,会丢失数据

recv_data, addr = socket_obj.recvfrom(1024)


本文参与了SegmentFault 思否面试闯关挑战赛,欢迎正在阅读的你也加入。

以上是 在python中使用socket编程创建一个简易聊天室的数据传输问题? 的全部内容, 来源链接: utcz.com/p/938786.html

回到顶部