一、初识python
python的由来想必大家都很了解,是吉多·范罗苏姆在1990年初设计出来的,它如今在很多程序中都有所体现,因为它简单,相对于C语言,C++,Java等语言要简单的多,小编在之前有C语言和Java编程的基础,所以在一周的时间内,认识了python,学习到了python的基础知识,并做出了python语言的服务器和端口,以及他们之间的相互连接。
二、python包的安装和使用
1.安装
python如果要完成其他很多项目的实现,或者去做其他目的,仅靠下载的python编辑器和python语言是行不通的,python有很多包,已经写好了很多框架,只需要去在idea、pycharm或者其他的集成开发环境下载需要的包,在终端里,使用以下代码,即可完成包的安装:
pip install 需要安装包的名称
2.使用
如果我们安装成功要去使用这个包的话,那我们需要去写代码的上面引用,还是用request举例子,还是跟Java使用类的方法一样,在开头写import 包的名字:
三、使用python语言,写出简单的服务器
我们先引用wxPython库,运用import wx引用进来,使用class myFrame创建一个类,通过继承和构造继承的调用创建一个具有指定ID、标题、位置和大小等的wxPython Frame窗口,这将会我们的主框架。
class myFrame(wx.Frame): def __init__(self): # 初始化框架 wx.Frame.__init__(self,None,id=1002,title='龙少的服务器',pos=wx.DefaultPosition,size=(400,450)) # 创建一个面板 pl=wx.Panel(self) # 创建一个BoxSizer box=wx.BoxSizer(wx.VERTICAL) # 创建一个FlexGridSizer fgz1=wx.FlexGridSizer(wx.HSCROLL)
我们再在原来的基础上,创建我们需要执行的按钮,再将按钮添加到我们fgz1里面。
# 创建一个启动服务器的按钮 start_server_btn=wx.Button(pl,label='启动服务器',size=(133,40)) # 创建一个保存聊天记录的按钮 record_btn=wx.Button(pl,label='保存聊天记录',size=(133,40)) # 创建一个停止服务的按钮 stop_server_btn=wx.Button(pl,label='停止服务',size=(133,40)) # 将按钮添加到FlexGridSizer fgz1.Add(start_server_btn,1,wx.TOP) fgz1.Add(record_btn,1,wx.TOP) fgz1.Add(stop_server_btn,1,wx.TOP) # 将FlexGridSizer添加到BoxSizer box.Add(fgz1,1,wx.ALIGN_CENTRE)
我们创建文本,设置show_text,这样我们就能看见传输的是什么,接收到的是什么;创建服务的ip地址;设置setsizer查看服务器是否启动;创建python的字典,保存等下我们运动的记录会话;再将我们上面写的按钮等功能,使用self.Bind绑定,等下我们讲赋予他们功能,使其实现。
# 创建一个文本控件 self.show_text=wx.TextCtrl(pl,size=(400,410),style=wx.TE_MULTILINE|wx.TE_READONLY) # 将文本控件添加到BoxSizer box.Add(self.show_text,1,wx.ALIGN_CENTRE) # 将BoxSizer添加到面板 pl.SetSizer(box) # 设置一个标志位,用于判断服务器是否启动 self.isOn=False # 设置服务器的IP地址和端口 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: sesion_socket,client_addr=self.server_socket.accept() user_name=sesion_socket.recv(1024).decode('utf-8') sesstion_thread=SesstionThread(sesion_socket,self,user_name) #传入字典 self.session_thread_dict[user_name]=sesstion_thread #启动线程 sesstion_thread.start() self.show_info_and_send_client('踏着七彩祥云进入了直播间',f'欢迎{user_name}进入直播间',time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())) #self.isOn值为False,执行关闭 self.server_socket.close() def show_info_and_send_client(self,data_source,data,datetime): # 格式化发送数据 send_data=f'{data_source}:{data} \n时间{datetime}' # 在UI界面中显示发送的数据 self.show_text.AppendText('-'*40+send_data+'\n') # 遍历所有客户端 for client in self.session_thread_dict.values(): # 判断客户端是否在线 if client.isOn: # 向客户端发送数据 client.client_socket.send(send_data.encode('utf-8'))
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: sesion_socket,client_addr=self.server_socket.accept() user_name=sesion_socket.recv(1024).decode('utf-8') sesstion_thread=SesstionThread(sesion_socket,self,user_name) #传入字典 self.session_thread_dict[user_name]=sesstion_thread #启动线程 sesstion_thread.start() self.show_info_and_send_client('踏着七彩祥云进入了直播间',f'欢迎{user_name}进入直播间',time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())) #self.isOn值为False,执行关闭 self.server_socket.close() def show_info_and_send_client(self,data_source,data,datetime): # 格式化发送数据 send_data=f'{data_source}:{data} \n时间{datetime}' # 在UI界面中显示发送的数据 self.show_text.AppendText('-'*40+send_data+'\n') # 遍历所有客户端 for client in self.session_thread_dict.values(): # 判断客户端是否在线 if client.isOn: # 向客户端发送数据 client.client_socket.send(send_data.encode('utf-8'))
这样的话,服务就已经安装完成,我们需要去编写一个运行代码,看他是否能够跑起来,运行的结果窗口小编将放在最后,演示他们完成连接。
if __name__=="__main__": # 创建一个wxPython应用程序 app=wx.App() # 创建一个myFrame窗口 server=myFrame() # 显示窗口 server.Show() # 运行应用程序的MainLoop() app.MainLoop()
四、使用python语言,写出简单的客户端,让它和服务器相连
客户端的代码和服务器的代码都相差不大,一样的创建一个框架,创建按钮,绑定按钮,再为连续按钮创建监听代码,小编前面的基础代码就不放了,只放绑定的按钮代码供大家参考。
def reset(self,event): #清空聊天框的内容 self.chat_text.SetValue() def dis_conn_server(self,event): # 向服务器发送“没钱不想看了” self.client_socket.send('没钱不想看了'.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: # 定义服务器IP和端口 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') # 将接收到的数据添加到TextCtrl中 self.show_text.AppendText('-'*40+'\n'+data+'\n')
跟服务器一样,在最后代码写完之后创建一个运行的代码,让它能跑起来。
if __name__=="__main__": # 导入wx模块 app=wx.App() # 获取用户输入的名称 name=input('请输入你的名称:') # 创建窗口 client=chuangkou(name) # 显示窗口 client.Show() # 运行主循环 app.MainLoop()
五、运行示例
终于写完了代码,我们来试试他的一些功能,用客户端连接服务器的时候,会有提示,不管是在集成开发环境还是在我们运行的代码里面都会有显示,让我们来试试吧。
六、在运行时可能会出现的错误
ConnectionRefusedError: [WinError 10061] 由于目标计算机积极拒绝:如果你的电脑是Windows11家庭版,那就是你所在python文件的磁盘权限不够,不能让python去修改并使用,这里小编有一个解决方法:
ModuleNotFoundError: No module named:这个错误是在我们第一天写完代码,装完包之后,再次打开这个代码时,会给我们报的错误,这是因为之前下载的包在其他的地方,我们需要去找到,并且再让这个py文件用这个包,就可以完美的解决。(这里小编使用的集成处理器是idea)
IndentationError:这个错误有很大的原因是因为代码的格式问题,可能是代码缩进问题,根据报错的行数去寻找缩进问题,就可以解决了。