当前位置: 首页 > 后端技术 > Python

7.Python网络编程

时间:2023-03-26 01:42:22 Python

网络编程Socket介绍Socket是应用层与TCP/IP协议族之间进行通信的中间软件抽象层,是一组接口。在设计模式上,Socket实际上是一种门面模式,将复杂的TCP/IP协议族隐藏在Socket接口的背后。对于用户来说,一套简单的接口就是全部,Socket组织数据以满足指定的协议。Socket是通用的网络编程接口,与网络层没有一一对应关系。Python中提供了socket.py标准库,这是一个非常低级的接口库。Protocolfamily:AF是AddressFamily的意思,用于socket()的第一个参数。AF_INETIPV4AF_INETIPV6Socket有两种SOCK_STREAM面向连接的流套接字。TCP协议SOCK_DGRAM是一个无连接的数据报文socket,而UDP协议TCP编程Socket编程需要两端,一般来说就是server端和client端。TCP服务器步骤:1)创建一个Socket对象2)绑定IP地址Address和端口Port。bind()方法端口对应进程3)开始监听,会监听指定的IP端口。听()方法。4)获取用于传输数据的Socket对象socket.accept()->(socketobject,addressinfo)accept方法阻塞等待客户端建立连接,返回一个Socket对象的二元组和客户地址。地址是远程客户端的地址,IPV4是一个二元组(clientaddr,port)5)接收数据:recv(bufsize[,flags])使用缓冲区接收数据发送数据:send(bytes)发送数据6)关闭资源实例importtime#TCPServersock=socket.socket()#DefaultIPv4,TCPip='127.0.0.1'port=9999#Integeraddr=(ip,port)sock.bind(addr)#绑定IP和港口袜子。listen()#监听conn,addrinfo=sock.accept()#返回一个socket对象和一个远程地址,默认阻塞data=conn.recv(1024)#接收数据print(data)msg='Datareceived{}'.format(data.decode())conn.send(msg.encode())#传输字节流数据conn.close()sock.close()socket常用方法方法说明socket.recv(bufsize[,flags])get数据,默认是阻塞的socket.recvfrom(bufsize[,flags])获取数据,返回一个二元组(bytes,address)socket.recv_into(buffer[,nbytes[,flags]])获取nbytesdata之后,它存储在缓冲区中。如果未指定nbytes或为0,则将缓冲区大小的数据存储到缓冲区中。返回接收到的字节数。socket.recvfrom_into(buffer[,nbytes[,flags])获取数据并将二元组(字节,地址)返回到缓冲区。socket.send(bytes[,flags)TCP发送数据socket.sendall(bytes[,flags)TCP发送所有数据,成功返回Nones.sendto(string[,flags],address)UDP发送数据socket.sendfile(file,offset=0,count=None)发送一个文件直到EOF,使用高性能的os.sendfile机制,返回发送的字节数。socket.makefile(mode='r',buffering=None,*,encoding=None,errors=None,newline=None)创建与此套接字关联的文件对象。makefile示例importthreadingimportsocketimportloggingimporttimelogging.basicConfig(level=logging.INFO,format='%(thread)d%(threadName)s%(message)s')#TCPServersock=socket.socket()#DefaultIPV4TCPip='127.0.0.1'port=9999#integeraddr=(ip,port)sock.bind(addr)#绑定IP和端口sock.listen()#monitorconn,addrinfo=sock.accept()#returnasocketobjectAnd一个远程地址,默认阻塞f=conn.makefile(mode='rw')line=f.read(10)print(line)f.write('Returnyourmsg:{}'.format(line))f.flush()f.close()UDPserver:大致类似于TCP,具体如下1)创建socket对象2)绑定IP和端口3)发送数据接收数据:socket.recvfrom(bufsize[,flags])sendData:socket.sendto(string,address)4)释放资源UDP客户端:1)创建socket对象2)发送数据:socket.sendto(string,address)向某个地址发送消息3)释放资源Socketserver套接字编程是太底层了,那么多语言都封装了underlyingsockets的API,Python的封装是socketserver模块SocketServer,简化了网络服务器的编写。它有4个同步类TCPServer、UDPServer、UnixStreamServer、UnixDatagramServer2Mixin类ForkingMixin和ThreadingMixin来支持异步。classForingUDPServer(ForkingMixin,UDPServer):PassclassForingTCPServer(ForkingMixin,TCPServer):PassclassThreadingUDPServer(ThreadingMixin,UDPServer):passclassThreadingTCPServer(ThreadingMixin,TCPServer):passProgramminginterface:socketserver.BaseServer(server_address,Class)需要提供服务器绑定地址信息,以及用于处理请求的RequestHandlerClass类。RequestHandlerClass类必须是BaseRequestHandlerClass的子类BaseRequestHandlerClass和用户连接(socket连接)的用户请求处理类。Server实例收到用户请求后,最终会实例化这个类。初始化后发送三个构造参数:request、client_address、server,后面可以在BaseRequestHandlerClass类的实例上传递。self.request是连接客户端的socket对象self.server是TCPServer本身self.client_address是客户端地址。它将一次调用3个函数,子类可以覆盖。BaseRequestHandlerClass:#子类要覆盖的方法defsetup(self):#每个连接初始化传递defhandle(self):#每个请求处理传递deffinish(self):#每个连接清理传递示例importsocketserverimportthreading#处理用户请求classMyHandler(socketserver.BaseRequestHandler):defsetup(self):super().setup()#TODOself.event=threading.Event()defhandle(self):super().handle()print(self.server,self.client_address,self.request)#循环,不循环,连接处理直接断开而不是self.event.is_set():data=self.request.recv(1024).decode()msg??="Yourmsg={}".format(data)print(msg)self.request.send(msg.encode())ifnotdata:breakdeffinish(self):super().finish()#Startserviceserver绑定addressADDR=('127.0.0.1',9999)server=socketserver.ThreadingTCPServer(ADDR,MyHandler)server.serve_forever()server.shutdown()server.server_close()总结:创建服务器的步骤1.通过BaseReq用户处理程序该类被子类化并覆盖handle()方法以创建将处理传入请求的请求处理类2.必须实例化服务器类,将服务器的地址和请求处理程序类传递给它3.调用服务器对象Thehandle_request()或server_forever()方法4.调用socket_close()关闭套接字。shutdown()方法等待停止forever()方法