防伪码:存在的,忘却了,红尘万丈,入眸幻灭
在进行网络编程前我们先来说说在网络中服务器与客户端是如何交互的,也就是传说中的TCP三次握手。
三次握手的目的是为了确认客户端与服务端都能接收到对方的信息,以下是三次握手的详细过程:
第一次握手:客户端给服务端发送请求包
此时服务端确认自己可以接收到客户端的请求包
客户端无法确认服务端是否接收到了自己发的请求包
第二次握手:服务端回复客户端
此时客户端确认自己发的请求包已被服务端收到,也确认自己可以正常接收服务端发来的包
服务端可以确认自己能接收到客户端的包,但不能确认客户端是否能收到自己发送的包
第三次握手:客户端回复服务端
此时客户端已无疑问
服务端也确认刚刚客户端收到了自己的回复包。两边都没问题了,开始通信
在python中提供了两个socket编程模块,分别是socket和socketserver。
我们先来说说socket编程需要经历哪些步骤:
客户端:
1、创建socket客户端连接对象
2、通过连接对象的connect()方法连接服务端
3、通过连接对象的send()方法给服务端发送信息或指令
4、通过连接对象的recv()方法接收服务端的返回信息
5、通过连接对象的close()方法断开连接
服务端:
1、创建socket服务端连接对象
2、通过连接对象的bind()方法绑定要监听的IP与端口
3、通过连接对象的listen()方法来监听
4、通过连接对象的accept()方法创建与客户端交互的子连接对象并等待客户端连接
5、接收并处理客户端的请求
6、将处理结果返回给客户端
由于socket无法支持多用户,多并发。于是就有了socketserver
socketserver最主要的作用就是实现并发处理。
socketserver有以下几种类型:
TCPServer:tcp协议
1
|
class socketserver.TCPServer(server_address,RequestHandlerClass,bind_and_activate = True )
|
ThreadingTCPServer:多线程,多并发的TCPServer
1
|
class socketserver.ThreadingTCPServer(server_address,RequestHandlerClass,bind_and_activate = True )
|
ForkingTCPServer:多进程,多并发的TCPServer #在windows中不能使用这个
1
|
class socketserver.ForkingTCPServer(server_address,RequestHandlerClass,bind_and_activate = True )
|
UDPServer:udp协议
1
|
class socketserver.UDPServer(server_address,RequestHandlerClass,bind_and_activate = True )
|
UnixStreamServer:tcp协议,Unix本机间不同进程间通信可以使用这个server
1
|
class socketserver.UnixStreamServer(server_address,RequestHandlerClass,bind_and_activate = True )
|
UnixDatagramServer:udp协议,Unix本机间不同进程间通信可以使用这个server
1
|
class socketserver.UnixDatagramServer(server_address,RequestHandlerClass,bind_and_activate = True )
|
BaseServer是所有Server类型的基类。
TCPServer继承了BaseServer,UnixStreamServer继承了TCPServer。
UDPServer继承了TCPServer,UnixDatagramServer继承了UDPServer。
BaseServer有以下这些方法:
fileno():返回文件描述符
handle_request():处理单个请求
serve_forever(poll_interval=0.5):处理多个请求
poll_interval用来设置多长时间检查一下是否有收到shutdown()请求
当收到shutdown()请求后,调用service_actions(),serve_forever将停止提供服务
shutdown():告诉serve_forever()让其停掉
server_close():关闭服务
创建socketserver的步骤:
1、创建一个BaseRequestHandlerclass的子类并在子类中重写handle()方法
这个子类用来处理客户端的请求
与客户端所有的交互都是在handle()方法中编写
2、实例化一个server(如TCPServer)类,并且将Server_IP和上一步创建的子类传给这个实例化的类(此处是 TCPServer)作为参数
3、调用第2步实例化出来的对象的方法,这里假定这个实例化出来的对象为server:
server.handle_request():只处理一个请求,处理完后退出
server.serve_forever():处理多个请求,永远执行
4、调用close()方法关闭server
重写BaseRequestHandlerclass类的handle()方法:
1
2
3
4
5
6
7
8
|
def handle( self ):
#self.request is the TCP socket connected to the client
self .data = self .request.recv( 1024 ).strip()
print ( "{} wrote:" . format ( self .client_address[ 0 ]))
print ( self .data)
#just send back the same data,but upper-cased
self .request.sendall( self .data.upper())
#sendall其实就是重复调用send,在这里也可以用send
|