鱼C论坛

 找回密码
 立即注册
查看: 1179|回复: 17

[新人报道] 用python做出局域网聊器

[复制链接]
发表于 2023-12-21 10:19:58 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
@FishC
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-12-21 10:20:16 | 显示全部楼层
当然可以!下面是一个简单的局域网聊天器的示例代码:
import socketimport threadingdef recv_msg(udp_socket):    while True:        data, addr = udp_socket.recvfrom(1024)        print('收到消息:', data.decode())def send_msg(udp_socket, dest_ip, dest_port):    while True:        msg = input('请输入要发送的消息:')        udp_socket.sendto(msg.encode(), (dest_ip, dest_port))def main():    udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)    udp_socket.bind(('', 8888))    dest_ip = input('请输入对方的IP地址:')    dest_port = int(input('请输入对方的端口号:'))    recv_thread = threading.Thread(target=recv_msg, args=(udp_socket,))    send_thread = threading.Thread(target=send_msg, args=(udp_socket, dest_ip, dest_port))    recv_thread.start()    send_thread.start()if __name__ == '__main__':    main()
你需要在两台电脑上分别运行这段代码,其中一台作为服务器,另一台作为客户端。在客户端上输入服务器的IP地址和端口号,然后就可以开始聊天了。注意,这个示例仅仅是最简单的局域网聊天器,没有任何安全措施,因此不适合在真实网络中使用。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-12-21 10:21:12 | 显示全部楼层
@FishC
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-12-21 10:21:24 | 显示全部楼层

你好!有什么编程问题我可以帮助你解答吗?

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-12-21 10:21:44 | 显示全部楼层
@FishC 用python创建局域网聊天器
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-12-21 10:21:58 | 显示全部楼层
fan200211 发表于 2023-12-21 10:21
@FishC 用python创建局域网聊天器

当然可以!下面是一个简单的局域网聊天器的代码示例:
import socketimport threading# 创建一个套接字s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 监听端口s.bind(('0.0.0.0', 8888))s.listen(5)def handle_client(client_socket):    while True:        # 接收数据        data = client_socket.recv(1024).decode('utf-8')        print("收到消息:" + data)        if data == 'exit':            print("客户端离开")            break        # 发送数据        response = input('回复:')        client_socket.send(response.encode('utf-8'))    client_socket.close()while True:    # 接受客户端连接请求    client_socket, address = s.accept()    print("客户端已连接:" + str(address))    # 开启线程处理客户端请求    client_thread = threading.Thread(target=handle_client, args=(client_socket,))    client_thread.start()
在这个例子中,我们使用了Socket模块创建一个TCP服务器。服务器监听端口8888。当客户端连接到服务器时,服务器会创建一个新的线程来处理客户端的请求。

每个客户端连接到服务器后,服务器会不停地接收客户端发送的消息,并将其显示在控制台上。然后服务器会等待用户输入,将用户输入的消息发送给客户端。

当客户端发送`exit`消息时,服务器会关闭与该客户端的连接,并等待下一个客户端连接。

这只是一个简单的示例,你可以根据自己的需求进行扩展和修改。例如,可以添加用户名、发送文件等功能。希望对你有帮助!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-12-21 10:27:48 | 显示全部楼层
FishC 发表于 2023-12-21 10:21
当然可以!下面是一个简单的局域网聊天器的代码示例:

用python做一个局域网聊天器写出服务器代码和客户端代码有什么需要在后续给你
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-12-21 10:29:05 | 显示全部楼层
fan200211 发表于 2023-12-21 10:27
用python做一个局域网聊天器写出服务器代码和客户端代 ...

当然可以!下面是一个基于UDP协议的局域网聊天器的示例代码:

服务器端代码:
import socketdef receive_messages(udp_socket):    while True:        data, addr = udp_socket.recvfrom(1024)        print('收到消息:', data.decode())def send_messages(udp_socket, dest_ip, dest_port):    while True:        msg = input('请输入要发送的消息:')        udp_socket.sendto(msg.encode(), (dest_ip, dest_port))def main():    udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)    udp_socket.bind(('', 8888))    dest_ip = input('请输入客户端的IP地址:')    dest_port = int(input('请输入客户端的端口号:'))    recv_thread = threading.Thread(target=receive_messages, args=(udp_socket,))    send_thread = threading.Thread(target=send_messages, args=(udp_socket, dest_ip, dest_port))    recv_thread.start()    send_thread.start()if __name__ == '__main__':    main()
客户端代码:
import socketdef receive_messages(udp_socket):    while True:        data, addr = udp_socket.recvfrom(1024)        print('收到消息:', data.decode())def send_messages(udp_socket, server_ip, server_port):    while True:        msg = input('请输入要发送的消息:')        udp_socket.sendto(msg.encode(), (server_ip, server_port))def main():    udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)    server_ip = input('请输入服务器的IP地址:')    server_port = int(input('请输入服务器的端口号:'))    recv_thread = threading.Thread(target=receive_messages, args=(udp_socket,))    send_thread = threading.Thread(target=send_messages, args=(udp_socket, server_ip, server_port))    recv_thread.start()    send_thread.start()if __name__ == '__main__':    main()
你需要在两台电脑上分别运行服务器端代码和客户端代码。服务器端代码会等待客户端连接,并接收客户端发送的消息。客户端代码会向服务器发送消息,同时接收服务器返回的消息。你需要确保两台电脑在同一个局域网中,并输入正确的IP地址和端口号。希望对你有帮助!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-12-21 10:35:32 | 显示全部楼层
FishC 发表于 2023-12-21 10:29
当然可以!下面是一个基于UDP协议的局域网聊天器的示例代码:

服务器端代码:

添加以下功能
1.2.1 用户登录
用户使用默认的服务器端口地址,输入昵称,接着点击‘登录’按钮,实现登录聊天系统。

1.2.2 群发消息
点击列表,然后选择点击消息中的群发,写好想发的消息后点发送按钮就可以群发消息。

1.2.3 一对一聊天
点击列表,然后选择点击消息中的对象,选择好想要发送的人,此,写好想发的消息后点击发送按钮就可以对当前那个人一对一的去聊天。

1.2.4 发送表情
用户点击‘表情’按钮,此时点击需要发送的表情即可发送
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-12-21 10:35:59 | 显示全部楼层
fan200211 发表于 2023-12-21 10:35
添加以下功能
1.2.1 用户登录
用户使用默认的服务器 ...

添加以上功能的代码如下:

服务器端代码:
import socketimport threadingdef handle_client(client_socket, client_address):    while True:        data = client_socket.recv(1024).decode()        if not data:            break        print(f'收到来自 {client_address} 的消息:{data}')        # 处理接收到的消息,根据消息类型进行相应的操作,如群发、一对一聊天等def main():    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)    server_port = 8888    server_socket.bind(('', server_port))    server_socket.listen(5)    print('服务器已启动,等待客户端连接...')        while True:        client_socket, client_address = server_socket.accept()        print(f'客户端 {client_address} 已连接')        client_thread = threading.Thread(target=handle_client, args=(client_socket, client_address))        client_thread.start()if __name__ == '__main__':    main()
客户端代码:
import socketfrom tkinter import *from tkinter import messageboxfrom emoji import emojizedef login():    nickname = nickname_entry.get()    if nickname:        # 连接服务器        server_ip = '服务器IP地址'        server_port = 8888        client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)        client_socket.connect((server_ip, server_port))                # 发送登录消息        login_msg = f'login:{nickname}'        client_socket.send(login_msg.encode())                # 启动接收消息线程        receive_thread = threading.Thread(target=receive_messages, args=(client_socket,))        receive_thread.start()                # 显示主界面        messagebox.showinfo('提示', '登录成功!')        login_frame.destroy()        show_main_window()    else:        messagebox.showwarning('警告', '请输入昵称!')def send_message():    message = message_entry.get()    if message:        # 发送消息        client_socket.send(message.encode())        message_entry.delete(0, END)def receive_messages(client_socket):    while True:        try:            data = client_socket.recv(1024).decode()            if not data:                break            # 处理接收到的消息,根据消息类型进行相应的操作,如群发、一对一聊天等        except Exception as e:            print(e)def show_main_window():    main_window = Tk()    main_window.title('聊天系统')        # 群发消息列表    group_listbox = Listbox(main_window)    group_listbox.pack(side=LEFT)        # 一对一聊天列表    private_listbox = Listbox(main_window)    private_listbox.pack(side=LEFT)        # 输入框和发送按钮    message_entry = Entry(main_window)    message_entry.pack(side=LEFT)    send_button = Button(main_window, text='发送', command=send_message)    send_button.pack(side=LEFT)        # 表情按钮    def send_emoji(emoji):        message_entry.insert(END, emoji)        emoji_button = Button(main_window, text='表情', command=lambda: send_emoji(emojize(':thumbs_up:')))    emoji_button.pack(side=LEFT)        main_window.mainloop()def main():    login_window = Tk()    login_window.title('登录')        nickname_label = Label(login_window, text='昵称:')    nickname_label.pack()    nickname_entry = Entry(login_window)    nickname_entry.pack()        login_button = Button(login_window, text='登录', command=login)    login_button.pack()        login_window.mainloop()if __name__ == '__main__':    main()
请注意将服务器端代码中的 `'服务器IP地址'` 替换为你实际的服务器IP地址。在客户端代码中,我们使用了Python的`tkinter`库创建了两个列表框用于显示群发消息列表和一对一聊天列表,以及一个输入框用于发送消息。同时,我们还添加了一个“表情”按钮,点击该按钮可以发送指定的表情符号。当用户点击登录按钮后,将会与服务器建立连接,并发送登录消息。然后,启动一个接收消息的新线程,不断接收来自服务器的消息并进行处理。如果收到群发消息,则将其显示在群发消息列表中;如果收到一对一聊天消息,则将其显示在对应的一对一聊天列表中。用户输入消息后,点击发送按钮即可发送消息给服务器。希望对你有帮助!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-12-21 10:43:27 | 显示全部楼层
FishC 发表于 2023-12-21 10:35
添加以上功能的代码如下:

服务器端代码:

客户端代码登录后出现Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python312\Lib\tkinter\__init__.py", line 1962, in __call__
    return self.func(*args)
           ^^^^^^^^^^^^^^^^
  File "C:\Users\Administrator\Desktop\PYTHON\pythonProject\01.py", line 8, in login
    nickname = nickname_entry.get()
               ^^^^^^^^^^^^^^
NameError: name 'nickname_entry' is not defined
Exception in Tkinter callback
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-12-21 10:43:38 | 显示全部楼层
fan200211 发表于 2023-12-21 10:43
客户端代码登录后出现Exception in Tkinter callback
...

抱歉,这是一个变量作用域的问题。在你的代码中,nickname_entry是在login函数内部定义的局部变量,无法在login函数外部访问。为了解决这个问题,你可以将nickname_entry变量声明为全局变量。修改后的代码如下:
import socketfrom tkinter import *from tkinter import messageboxfrom emoji import emojize# 全局变量nickname_entry = Nonemessage_entry = Noneclient_socket = Nonedef login():    global nickname_entry, client_socket  # 声明全局变量    nickname = nickname_entry.get()    if nickname:        # 连接服务器        server_ip = '服务器IP地址'        server_port = 8888        client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)        client_socket.connect((server_ip, server_port))        # 发送登录消息        login_msg = f'login:{nickname}'        client_socket.send(login_msg.encode())        # 启动接收消息线程        receive_thread = threading.Thread(target=receive_messages, args=(client_socket,))        receive_thread.start()        # 显示主界面        messagebox.showinfo('提示', '登录成功!')        login_frame.destroy()        show_main_window()    else:        messagebox.showwarning('警告', '请输入昵称!')# 其他代码保持不变...
请记得将`'服务器IP地址'`替换为你实际的服务器IP地址。通过在`login()`函数内部添加`global nickname_entry, client_socket`语句,我们将nickname_entry和client_socket变量声明为全局变量,从而可以在整个程序中进行访问。

希望这次能解决你的问题!如果还有其他疑问,请随时提出。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-12-21 10:44:48 | 显示全部楼层
FishC 发表于 2023-12-21 10:43
抱歉,这是一个变量作用域的问题。在你的代码中,nickname_entry是在login函数内部定义的局部变量,无法 ...

全部代码写出来
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-12-21 10:45:10 | 显示全部楼层

当然可以!下面是一个完整的局域网聊天器的示例代码:
import socketfrom tkinter import *from tkinter import messageboximport threading# 全局变量nickname_entry = Nonemessage_entry = Noneclient_socket = Nonedef login():    global nickname_entry, client_socket  # 声明全局变量    nickname = nickname_entry.get()    if nickname:        # 连接服务器        server_ip = '服务器IP地址'        server_port = 8888        client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)        client_socket.connect((server_ip, server_port))                # 发送登录消息        login_msg = f'login:{nickname}'        client_socket.send(login_msg.encode())        # 启动接收消息线程        receive_thread = threading.Thread(target=receive_messages, args=(client_socket,))        receive_thread.start()        # 显示主界面        messagebox.showinfo('提示', '登录成功!')        login_frame.destroy()        show_main_window()    else:        messagebox.showwarning('警告', '请输入昵称!')def send_message():    message = message_entry.get()    if message:        client_socket.send(message.encode())        message_entry.delete(0, END)    else:        messagebox.showwarning('警告', '请输入消息内容!')def receive_messages(client_socket):    while True:        message = client_socket.recv(1024).decode()        print('收到消息:', message)def show_main_window():    main_window = Tk()    main_window.title('局域网聊天器')    main_window.geometry('400x300')    message_label = Label(main_window, text='请输入消息:')    message_label.pack()    global message_entry    message_entry = Entry(main_window)    message_entry.pack()    send_button = Button(main_window, text='发送', command=send_message)    send_button.pack()    main_window.mainloop()if __name__ == '__main__':    login_frame = Tk()    login_frame.title('登录')    login_frame.geometry('300x200')    nickname_label = Label(login_frame, text='昵称:')    nickname_label.pack()    global nickname_entry    nickname_entry = Entry(login_frame)    nickname_entry.pack()    login_button = Button(login_frame, text='登录', command=login)    login_button.pack()    login_frame.mainloop()
请记得将`'服务器IP地址'`替换为你实际的服务器IP地址。通过在`login()`函数内部添加`global nickname_entry, client_socket`语句,我们将nickname_entry和client_socket变量声明为全局变量,从而可以在整个程序中进行访问。

这段代码创建了一个简单的GUI界面,用户可以输入昵称登录到局域网聊天服务器,并发送和接收消息。每个用户都需要运行这段代码并输入相同的服务器IP地址才能进行通信。

希望这次能解决你的问题!如果还有其他疑问,请随时提出。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-12-21 10:47:16 | 显示全部楼层
FishC 发表于 2023-12-21 10:45
当然可以!下面是一个完整的局域网聊天器的示例代码:

出现了这个  File "C:\Users\Administrator\Desktop\PYTHON\pythonProject\01.py", line 71
    global nickname_entry
    ^^^^^^^^^^^^^^^^^^^^^
SyntaxError: name 'nickname_entry' is assigned to before global declaration
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-12-21 10:47:29 | 显示全部楼层
fan200211 发表于 2023-12-21 10:47
出现了这个  File "C:\Users\Administrator\Desktop\P ...

抱歉,出现了一个错误。在使用`global`关键字声明全局变量之前,应该先对变量进行赋值。你可以稍微修改一下代码,将`global`关键字的位置移动到正确的地方。请参考以下代码示例:
import socketfrom tkinter import *from tkinter import messageboximport threading# 全局变量nickname_entry = Nonemessage_entry = Noneclient_socket = Nonedef login():    global nickname_entry, client_socket  # 声明全局变量    nickname = nickname_entry.get()    if nickname:        # 连接服务器        server_ip = '服务器IP地址'        server_port = 8888        client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)        client_socket.connect((server_ip, server_port))        # 发送登录消息        login_msg = f'login:{nickname}'        client_socket.send(login_msg.encode())        # 启动接收消息线程        receive_thread = threading.Thread(target=receive_messages, args=(client_socket,))        receive_thread.start()        # 显示主界面        messagebox.showinfo('提示', '登录成功!')        login_frame.destroy()        show_main_window()    else:        messagebox.showwarning('警告', '请输入昵称!')def send_message():    message = message_entry.get()    if message:        client_socket.send(message.encode())        message_entry.delete(0, END)    else:        messagebox.showwarning('警告', '请输入消息内容!')def receive_messages(client_socket):    while True:        message = client_socket.recv(1024).decode()        print('收到消息:', message)def show_main_window():    main_window = Tk()    main_window.title('局域网聊天器')    main_window.geometry('400x300')    message_label = Label(main_window, text='请输入消息:')    message_label.pack()    global message_entry    message_entry = Entry(main_window)    message_entry.pack()    send_button = Button(main_window, text='发送', command=send_message)    send_button.pack()    main_window.mainloop()if __name__ == '__main__':    login_frame = Tk()    login_frame.title('登录')    login_frame.geometry('300x200')    nickname_label = Label(login_frame, text='昵称:')    nickname_label.pack()    nickname_entry = Entry(login_frame)    nickname_entry.pack()    login_button = Button(login_frame, text='登录', command=login)    login_button.pack()    login_frame.mainloop()
请记得将`'服务器IP地址'`替换为你实际的服务器IP地址。现在应该不会再出现之前的错误了。如果还有其他问题,请随时提问。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-12-21 10:50:00 | 显示全部楼层
FishC 发表于 2023-12-21 10:47
抱歉,出现了一个错误。在使用`global`关键字声明全局变量之前,应该先对变量进行赋值。你可以稍微修改一 ...

能发消息但是没有聊天框
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-12-21 10:50:11 | 显示全部楼层
fan200211 发表于 2023-12-21 10:50
能发消息但是没有聊天框

抱歉让你困惑了,以下是修改后的代码,包括一个聊天框来显示接收到的消息:import socketfrom tkinter import *from tkinter import messageboximport threading# 全局变量nickname_entry = Nonemessage_entry = Noneclient_socket = Nonedef login():    global nickname_entry, client_socket  # 声明全局变量    nickname = nickname_entry.get()    if nickname:        # 连接服务器        server_ip = '服务器IP地址'        server_port = 8888        client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)        client_socket.connect((server_ip, server_port))        # 发送登录消息        login_msg = f'login:{nickname}'        client_socket.send(login_msg.encode())        # 启动接收消息线程        receive_thread = threading.Thread(target=receive_messages, args=(client_socket,))        receive_thread.start()        # 显示主界面        messagebox.showinfo('提示', '登录成功!')        login_frame.destroy()        show_main_window()    else:        messagebox.showwarning('警告', '请输入昵称!')def send_message():    message = message_entry.get()    if message:        client_socket.send(message.encode())        message_entry.delete(0, END)    else:        messagebox.showwarning('警告', '请输入消息内容!')def receive_messages(client_socket):    while True:        try:            message = client_socket.recv(1024).decode()            chat_box.insert(END, message+'\n')        except OSError:            breakdef show_main_window():    main_window = Tk()    main_window.title('局域网聊天器')    main_window.geometry('400x300')    chat_box = Text(main_window)    chat_box.pack(side=TOP)    scrollbar = Scrollbar(main_window, orient=VERTICAL)    scrollbar.pack(side=RIGHT, fill=Y)    chat_box.config(yscrollcommand=scrollbar.set)    scrollbar.config(command=chat_box.yview)    global message_entry    message_entry = Entry(main_window)    message_entry.pack(side=BOTTOM)    send_button = Button(main_window, text='发送', command=send_message)    send_button.pack(side=BOTTOM)    main_window.mainloop()if __name__ == '__main__':    login_frame = Tk()    login_frame.title('登录')    login_frame.geometry('300x200')    nickname_label = Label(login_frame, text='昵称:')    nickname_label.pack()    nickname_entry = Entry(login_frame)    nickname_entry.pack()    login_button = Button(login_frame, text='登录', command=login)    login_button.pack()    login_frame.mainloop()请将`'服务器IP地址'`替换为你实际的服务器IP地址。现在,你应该可以看到一个带有聊天框的界面,用于显示接收到的消息。如果还有其他问题,请随时提问。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-22 23:25

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表