服务端实现
import threading
import timeimport wx
from socket import socket, AF_INET, SOCK_STREAMclass LServer ( wx. Frame) : def __init__ ( self) : wx. Frame. __init__( self, None , id = 1002 , title= 'L服务器端界面' , pos= wx. DefaultPosition, size= ( 400 , 450 ) ) pl = wx. Panel( self) box = wx. BoxSizer( wx. VERTICAL) fgz1 = wx. FlexGridSizer( wx. HSCROLL) start_server_btn = wx. Button( pl, size= ( 133 , 40 ) , label= '启动服务' ) record_btn = wx. Button( pl, size= ( 133 , 40 ) , label= '保存记录' ) stop_server_btn = wx. Button( pl, size= ( 133 , 40 ) , label= '停止服务' ) fgz1. Add( start_server_btn, 1 , wx. TOP | wx. LEFT) fgz1. Add( record_btn, 1 , wx. TOP | wx. CENTRE) fgz1. Add( stop_server_btn, 1 , wx. TOP | wx. RIGHT) box. Add( fgz1, 1 , wx. ALIGN_CENTRE) self. show_text = wx. TextCtrl( pl, size= ( 400 , 410 ) , style= wx. TE_MULTILINE | wx. TE_READONLY) box. Add( self. show_text, 1 , wx. ALIGN_CENTRE) pl. SetSizer( box) '''-----------------------------以上代码为界面的绘制代码-----------------------------------''' '''------------------------------设置服务器功能实现的必要属性----------------------------------''' self. isOn = False self. host_port = ( '' , 8888 ) self. server_socket = socket( AF_INET, SOCK_STREAM) self. server_socket. bind( self. host_port) self. server_socket. listen( 5 ) self. session_thread_dict = { } '''----------------------------------------------------------------''' self. Bind( wx. EVT_BUTTON, self. start_server, start_server_btn) self. Bind( wx. EVT_BUTTON, self. save_record, record_btn) self. Bind( wx. EVT_BUTTON, self. stop_server, stop_server_btn) def stop_server ( self, event) : print ( '服务器已停止服务' ) self. isOn= False def save_record ( self, event) : record_data= self. show_text. GetValue( ) with open ( 'record.log' , 'w' , encoding= 'utf-8' ) as file : file . write( record_data) def start_server ( self, event) : if not self. isOn: self. isOn = True main_thread = threading. Thread( target= self. do_work) main_thread. daemon = True main_thread. start( ) def do_work ( self) : while self. isOn: session_socket, client_addr = self. server_socket. accept( ) user_name = session_socket. recv( 1024 ) . decode( 'utf-8' ) session_thread = SessionThread( session_socket, user_name, self) self. session_thread_dict[ user_name] = session_threadsession_thread. start( ) self. show_info_and_send_client( '服务器通知' , f'欢迎 { user_name} 进入聊天室!' , time. strftime( '%Y-%m-%d %H:%M:%S' , time. localtime( ) ) ) self. server_socket. close( ) def show_info_and_send_client ( self, data_source, data, data_time) : send_data = f' { data_source} : { data} \n时间: { data_time} ' self. show_text. AppendText( '-' * 40 + '\n' + send_data + '\n' ) for client in self. session_thread_dict. values( ) : if client. isOn: client. client_socket. send( send_data. encode( 'utf-8' ) ) class SessionThread ( threading. Thread) : def __init__ ( self, client_socket, user_name, server) : threading. Thread. __init__( self) self. client_socket = client_socketself. user_name = user_nameself. server = serverself. isOn = True def run ( self) : print ( f'客户端: { self. user_name} 已经与服务端建立连接.' ) while self. isOn: data = self. client_socket. recv( 1024 ) . decode( 'utf-8' ) ; if data == 'C-DISCONNECT-S' : self. isOn = False self. server. show_info_and_send_client( '服务器通知' , f' { self. user_name} 离开了聊天室' , time. strftime( '%Y-%m-%d %H:%M:%S' , time. localtime( ) ) ) else : self. server. show_info_and_send_client( self. user_name, data, time. strftime( '%Y-%m-%d %H:%M:%S' , time. localtime( ) ) ) self. client_socket. close( ) if __name__ == '__main__' : app = wx. App( ) client = LServer( ) client. Show( ) app. MainLoop( )
客户端实现
import threadingimport wx
from socket import socket, AF_INET, SOCK_STREAMclass LClinet ( wx. Frame) : def __init__ ( self, clent_name) : wx. Frame. __init__( self, None , id = 1001 , title= clent_name + '的客户端界面' , pos= wx. DefaultPosition, size= ( 400 , 600 ) ) pl = wx. Panel( self) box = wx. BoxSizer( wx. VERTICAL) fgz1 = wx. FlexGridSizer( wx. HSCROLL) connect_btn = wx. Button( pl, size= ( 200 , 40 ) , label= '连接' ) disconnect_btn = wx. Button( pl, size= ( 200 , 40 ) , label= '断开' ) fgz1. Add( connect_btn, 1 , wx. TOP | wx. LEFT) fgz1. Add( disconnect_btn, 1 , wx. TOP | wx. RIGHT) box. Add( fgz1, 1 , wx. ALIGN_CENTRE) self. show_text = wx. TextCtrl( pl, size= ( 400 , 210 ) , style= wx. TE_MULTILINE | wx. TE_READONLY) box. Add( self. show_text, 1 , wx. ALIGN_CENTRE) self. chat_text = wx. TextCtrl( pl, size= ( 400 , 210 ) , style= wx. TE_MULTILINE) box. Add( self. chat_text, 1 , wx. ALIGN_CENTRE) fgz2 = wx. FlexGridSizer( wx. HSCROLL) reset_btn = wx. Button( pl, size= ( 200 , 40 ) , label= '重置' ) send_btn = wx. Button( pl, size= ( 200 , 40 ) , label= '发送' ) fgz2. Add( reset_btn, 1 , wx. TOP | wx. LEFT) fgz2. Add( send_btn, 1 , wx. TOP | wx. LEFT) box. Add( fgz2, 1 , wx. ALIGN_CENTRE) pl. SetSizer( box) '''------------------以上代码时客户端界面的绘制---------------------''' self. Bind( wx. EVT_BUTTON, self. connect_to_server, connect_btn) self. client_name = clent_nameself. isConnected = False self. client_socket = None self. Bind( wx. EVT_BUTTON, self. send_to_server, send_btn) self. Bind( wx. EVT_BUTTON, self. disconnect_to_server, disconnect_btn) self. Bind( wx. EVT_BUTTON, self. reset, reset_btn) def reset ( self, event) : self. chat_text. SetValue( '' ) def disconnect_to_server ( self, event) : self. client_socket. send( 'C-DISCONNECT-S' . encode( 'utf-8' ) ) self. isConnected= False def send_to_server ( self, event) : if self. isConnected: input_data = self. chat_text. GetValue( ) if input_data != '' : self. client_socket. send( input_data. encode( 'utf-8' ) ) self. chat_text. SetValue( '' ) def connect_to_server ( self, event) : print ( f'客户端 { self. client_name} 连接服务器成功' ) if not self. isConnected: server_host_port = ( '127.0.0.1' , 8888 ) self. client_socket = socket( AF_INET, SOCK_STREAM) self. client_socket. connect( server_host_port) self. client_socket. send( self. client_name. encode( 'utf-8' ) ) client_thread = threading. Thread( target= self. recv_data) client_thread. daemon = True self. isConnected = True client_thread. start( ) def recv_data ( self) : while self. isConnected: data = self. client_socket. recv( 1024 ) . decode( 'utf-8' ) self. show_text. AppendText( '-' * 40 + '\n' + data + '\n' ) if __name__ == '__main__' : app = wx. App( ) name = input ( '请输入客户端名称:' ) client = LClinet( name) client. Show( ) app. MainLoop( )