1. 客户端的开发
1. 界面开发
import wx
import threading
from socket import *
class Client(wx.Frame):
def __init__(self):
self.name = 'Jarry'
self.isConnected = False
self.client_socket = None
wx.Frame.__init__(self,None,title=self.name + "聊天客户端",size=(400,600),pos=(100,100))
# 创建面板
self.pl = wx.Panel(self,size=(400,600),pos=(100,100))
# 创建按钮
# 加入聊天室按钮
self.conn_btn = wx.Button(self.pl,label="加入聊天室",size=(140,50),pos=(30,10))
# 断开聊天室按钮
self.dis_conn_btn = wx.Button(self.pl, label="离开聊天室", size=(140, 50), pos=(230, 10))
# 清空按钮
self.clear_btn = wx.Button(self.pl, label="清空", size=(140, 50), pos=(30,500))
# 发送按钮
self.send_btn = wx.Button(self.pl, label="加入聊天室", size=(140, 50), pos=(230,500))
# 创建文本
# 聊天框文本
self.chat_text = wx.TextCtrl(self.pl,size=(370,220),pos=(10,70),style=wx.TE_READONLY | wx.TE_MULTILINE)
# 发送文本框
self.send_text = wx.TextCtrl(self.pl, size=(370, 140), pos=(10, 310), style=wx.TE_MULTILINE)\
# 按钮绑定事件
self.Bind(wx.EVT_BUTTON,self.conn,self.conn_btn)
self.Bind(wx.EVT_BUTTON, self.dis_conn, self.dis_conn_btn)
self.Bind(wx.EVT_BUTTON, self.clear, self.clear_btn)
self.Bind(wx.EVT_BUTTON, self.send, self.send_btn)
def conn(self,event):
print("点击加入聊天室按钮")
def dis_conn(self,event):
print("点击离开聊天室按钮")
def clear(self,event):
print("点击清除按钮")
def send(self,event):
print("点击发送按钮")
if __name__ == "__main__":
# 创建应用程序对象
app = wx.App()
# 创建客户端窗口
client = Client()
# 显示客户端
client.Show()
# 循环显示
app.MainLoop()
2. 客户端实现
import wx
import threading
from socket import *
class Client(wx.Frame):
def __init__(self):
self.name = 'Jarry'
self.isConnected = False
self.client_socket = None
wx.Frame.__init__(self,None,title=self.name + "聊天客户端",size=(400,600),pos=(100,100))
# 创建面板
self.pl = wx.Panel(self,size=(400,600),pos=(100,100))
# 创建按钮
# 加入聊天室按钮
self.conn_btn = wx.Button(self.pl,label="加入聊天室",size=(140,50),pos=(30,10))
# 断开聊天室按钮
self.dis_conn_btn = wx.Button(self.pl, label="离开聊天室", size=(140, 50), pos=(230, 10))
# 清空按钮
self.clear_btn = wx.Button(self.pl, label="清空", size=(140, 50), pos=(30,500))
# 发送按钮
self.send_btn = wx.Button(self.pl, label="发送", size=(140, 50), pos=(230,500))
# 创建文本
# 聊天框文本
self.chat_text = wx.TextCtrl(self.pl,size=(370,220),pos=(10,70),style=wx.TE_READONLY | wx.TE_MULTILINE)
# 发送文本框
self.send_text = wx.TextCtrl(self.pl, size=(370, 140), pos=(10, 310), style=wx.TE_MULTILINE)\
# 按钮绑定事件
self.Bind(wx.EVT_BUTTON,self.conn,self.conn_btn)
self.Bind(wx.EVT_BUTTON, self.dis_conn, self.dis_conn_btn)
self.Bind(wx.EVT_BUTTON, self.clear, self.clear_btn)
self.Bind(wx.EVT_BUTTON, self.send, self.send_btn)
def conn(self,event):
print("加入聊天室")
if self.isConnected == False:
self.isConnected = True
self.client_socket = socket()
self.client_socket.connect(("127.0.0.1",8999))
self.client_socket.send(self.name.encode("UTF-8"))
main_thread = threading.Thread(target=self.recv_data)
main_thread.daemon = True
main_thread.start()
def recv_data(self):
while self.isConnected:
text = self.client_socket.recv(1024).decode("UTF-8")
self.chat_text.AppendText(text+'\n')
def dis_conn(self,event):
self.client_socket.send("断开连接".encode("UTF-8"))
self.isConnected = False
def clear(self,event):
self.chat_text.Clear()
def send(self,event):
if self.isConnected:
text = self.send_text.GetValue()
if text != "":
self.client_socket.send(text.encode("UTF-8"))
self.send_text.Clear()
if __name__ == "__main__":
# 创建应用程序对象
app = wx.App()
# 创建客户端窗口
client = Client()
# 显示客户端
client.Show()
# 循环显示
app.MainLoop()
2. 服务端开发
1. 服务端界面开发
import socket
import wx
from socket import *
import threading
from concurrent.futures import ThreadPoolExecutor
class Server(wx.Frame):
def __init__(self):
self.isOn = False
# 创建socket对象
self.server_socket = socket()
# 绑定IP和端口号
self.server_socket.bind(("0.0.0.0",8999))
# 添加监听
self.server_socket.listen(5)
wx.Frame.__init__(self,None,title="客户端",size=(400,600),pos=(100,100))
# 创建面板
self.pl = wx.Panel(self,size=(400,600),pos=(100,100))
# 启动服务器按钮
self.start_server_btn = wx.Button(self.pl,size=(140,50),pos=(30,10),label = "启动服务器")
# 保存聊天记录按钮
self.save_text_btn = wx.Button(self.pl, size=(140, 50), pos=(220, 10), label="保存聊天记录")
# 聊天记录框
self.chat_text = wx.TextCtrl(self.pl,size=(370, 450), pos=(10, 80),style = wx.TE_MULTILINE)
self.Bind(wx.EVT_BUTTON,self.start_server,self.start_server_btn)
self.Bind(wx.EVT_BUTTON,self.save_text,self.save_text_btn)
def start_server(self,event):
if self.isOn == False:
self.isOn = True
def save_text(self,event):
pass
if __name__ == "__main__":
app = wx.App()
server = Server()
server.Show()
app.MainLoop()
2. 服务端实现
实现部分
import socket
import wx
from socket import *
import threading
from concurrent.futures import ThreadPoolExecutor
class Server(wx.Frame):
def __init__(self):
self.isOn = False
# 创建socket对象
self.server_socket = socket()
# 绑定IP和端口号
self.server_socket.bind(("0.0.0.0",8999))
# 添加监听
self.server_socket.listen(5)
wx.Frame.__init__(self,None,title="聊天室服务端",size=(400,600),pos=(800,100))
# 创建面板
self.pl = wx.Panel(self,size=(400,600),pos=(800,100))
# 启动服务器按钮
self.start_server_btn = wx.Button(self.pl,size=(140,50),pos=(30,10),label = "启动服务器")
# 保存聊天记录按钮
self.save_text_btn = wx.Button(self.pl, size=(140, 50), pos=(220, 10), label="保存聊天记录")
# 聊天记录框
self.chat_text = wx.TextCtrl(self.pl,size=(370, 450), pos=(10, 80),style = wx.TE_MULTILINE)
self.Bind(wx.EVT_BUTTON,self.start_server,self.start_server_btn)
self.Bind(wx.EVT_BUTTON,self.save_text,self.save_text_btn)
# 保存所有客户端
self.client_thread_dict = {}
# 创建线程池
self.client_pool = ThreadPoolExecutor(max_workers=10)
def start_server(self,event):
print("启动服务器")
if self.isOn == False:
self.isOn = True
# 创建主线程
main_thread = threading.Thread(target=self.main_thread_fun)
main_thread.daemon = True
main_thread.start()
def main_thread_fun(self):
while self.isOn:
client_socket,client_address = self.server_socket.accept()
print(f"客户端地址{client_address}")
client_name = client_socket.recv(1024).decode("UTF-8")
client_thread = ClientThread(client_socket,client_name,self)
self.client_thread_dict[client_name] = client_thread
self.client_pool.submit(client_thread.run)
self.send("【服务器信息】:欢迎%s加入聊天室"%client_name)
def send(self,text):
self.chat_text.AppendText(text+"\n")
for client in self.client_thread_dict.values():
if client.isOn:
client.client_socket.send(text.encode("UTF-8"))
def save_text(self, event):
record = self.chat_text.GetValue()
with open(file="Record.log", mode="a+", encoding="GBK") as f:
f.write(record)
class ClientThread(threading.Thread):
def __init__(self,socket,name,server):
threading.Thread.__init__(self)
self.client_socket = socket
self.client_name = name
self.server = server
self.isOn = True
def run(self):
while self.isOn:
text = self.client_socket.recv(1024).decode("UTF-8")
if text == "断开连接":
self.isOn = False
self.server.send("【服务器消息】:%s离开了聊天室"%self.client_name)
else:
self.server.send("【%s】:%s"%(self.client_name,text))
self.client_socket.close()
if __name__ == "__main__":
app = wx.App()
server = Server()
server.Show()
app.MainLoop()
3. 知识点总结
1. socket套接字


服务端
import socket
# 创建一个TCP套接字
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 绑定主机和端口
server_socket.bind(('127.0.0.1', 12345))
# 监听连接
server_socket.listen()
print("Server is listening for incoming connections...")
# 接受客户端连接
client_socket, client_address = server_socket.accept()
print(f"Connection established with {client_address}")
# 接收数据
data = client_socket.recv(1024)
print(f"Received data: {data.decode('utf-8')}")
# 发送响应
response = "Hello, client!"
client_socket.send(response.encode('utf-8'))
# 关闭连接
client_socket.close()
server_socket.close()
客户端
import socket
# 创建一个TCP套接字
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 连接到服务器
client_socket.connect(('127.0.0.1', 12345))
# 发送数据
data_to_send = "Hello, server!"
client_socket.send(data_to_send.encode('utf-8'))
# 接收响应
response = client_socket.recv(1024)
print(f"Received response: {response.decode('utf-8')}")
# 关闭连接
client_socket.close()
2. 线程
博客待整理
https://blog.csdn.net/weixin_49806206/article/details/134543871?spm=1001.2014.3001.5502
13万+

被折叠的 条评论
为什么被折叠?



