python实现一个简单的广域网内的GUI聊天室

1. 聊天室介绍

本次实验实现的是在广域网上的聊天室,不同于局域网的聊天室,只要在云服务器上运行服务端脚本,任何一台运行客户端脚本的linux主机都可以进行互发消息。

2. 开发环境

  • 服务器:华为云服务器(Ubuntu18.04)。
  • 用来测试的客户端:自己的VMware里的两台虚拟机:Ubuntu20.04和Ubuntu18.04。
  • 要用到python的Tkinter库。菜鸟教程
  • python3网络编程。菜鸟教程
  • 服务端开发编辑器:vscode和Remote-ssh插件(这个插件可以实现在vscode中连接到服务器的bash窗口,把文件放到vscode中编辑)。

3. 服务端代码(chat_server.py)实现

  1. chat_server.py代码倒数第4行的绑定的服务器的IP地址应该是服务器的内网地址,不是公网地址,即</font在这里插入图片描述
  2. 监听TCP:9988端口,并在华为云服务器后台的安全组策略中开放9988端口。
    在这里插入图片描述
#!/usr/bin/python3
#-*- coding:UTF-8 -*-
import socketserver

class Chat_server(socketserver.StreamRequestHandler):
   def handle(self):
       conn = self.request
       try:
           while True:
               data_b = conn.recv(1024)
               print('data_b = ', data_b)
               if conns.count(conn) == 0:
                   conns.append(conn)
                   name_s = data_b.decode('utf-8')
                   users.setdefault(conn, name_s)
                   data_s = ''
                   data = 'Welcome' + name_s + '!'
               else:
                   name_s = users.get(conn)
                   data_s = data_b.decode('utf-8')
                   data = name_s + ': ' + data_s
               print('data = ', data)
               data_b = data.encode('utf-8')
               for cn in conns:
                   cn.send(data_b)
               if data_s.upper()[0:3] == 'BYE':
                   print('%s is exited!' % name_s)
                   conns.remove(conn)
                   del(users[conn])
                   break;
       except Exception as e:
           print('Error is ', e)
conns = []
users = {}
ip = '192.168.0.220'  #注意这里是服务器的内网地址不是公网地址
server = socketserver.ThreadingTCPServer((ip, 9988), Chat_server)
print('Wait for TCP connecting...')
server.serve_forever()

4. 客户端代码(chat_client.py)实现

这里的IP地址应该是服务器的公网地址。

#!/usr/bin/python3
# coding:utf-8
import socket
import threading
import tkinter as tk
def send_msg():
    txt = bt_txt.get()
    if txt == 'Logon':
        bt_txt.set('Send')
    msg = et_txt.get()
    et_txt.set('')
    print('msg = ', msg)
    msg_b = msg.encode('utf-8')
    s.send(msg_b)
    if msg.upper()[0:3] == 'BYE':
        chat_send.config(state = tk.DISABLED)
        s.close()

def receive_msg():
    while True:
        try:
            data_b = s.recv(1024)
            data_s = data_b.decode('utf-8')
            print('data_s = ', data_s)
            chat_list.insert(tk.END, data_s)
            chat_list.see(tk.END)
        except Exception as e:
            print('Error is ', e)
            print('Exist!')
            break

#ip = '192.168.213.128'
ip = '124.70.13.161'
#ip = 'localhost'

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((ip, 9988))
t = threading.Thread(target = receive_msg)
t.start()
root = tk.Tk()
root.title('Chatting room')
root.geometry('300x350')
root.resizable(width = False, height = True)
fm = tk.Frame(root, width=300, height=300)
scrl = tk.Scrollbar(fm)
chat_list = tk.Listbox(fm, width=300, selectmode=tk.BROWSE)
chat_list.configure(yscrollcommand=scrl.set)
scrl['command'] = chat_list.yview
bt_txt = tk.StringVar(value='Logon')
et_txt = tk.StringVar(value='')
chat_txt = tk.Entry(root, bd=5, width=280, textvariable=et_txt)
chat_send = tk.Button(root, textvariable=bt_txt, command=send_msg)
scrl.pack(side=tk.RIGHT, fill=tk.Y)
chat_txt.pack()
chat_send.pack()
chat_list.pack()
fm.pack()
root.mainloop()

5. 测试

  1. 先在服务器上启动脚本。
sudo chmod +x chat_server.py
sudo ./chat_server.py
  1. 在客户端1和2上启动客户端脚本
sudo apt-get install python3-tk
sudo chmod +x chat_client.py
sudo ./chat_client.py
  1. 在客户端上输入消息,第一次输入消息是确定用户的名字。第二次之后就可以正常互发消息了。最后输入bye退出聊天。

客户端:
在这里插入图片描述
在这里插入图片描述
服务端:
在这里插入图片描述

参考资料

  • 《Python网络编程(Linux)》清华大学出版社
  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值