socket模块的使用
1.模仿CS 架构模型
1.1简版
服务器端
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import socket server = socket.socket() #创建一个服务器对象 ip_port = ('192.168.15.79',8080)#创建一个元组 server.bind(ip_port) #将服务器和ip地址进行绑定 server.listen(3) #设置服务器可以同时监听多少个客户端 con,addr =server.accept()#接收客户端发送过来的东西,如果协商成功,就建立相应的隧道 # print(con)#两者协商通信的协议,使用的ip地址和端口号 # #<socket.socket fd=96, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('192.168.15.79', 8080), raddr=('192.168.15.79', 57945)> print(addr)#('192.168.15.79', 57945) 连接的客户端的地址和端口号 Client = con.recv(1024)#设置接收的最大的文件的大小,并将接收到的信息进行赋值 print('客户端消息:',Client) con.send(b'you are over')#向客户端发送相关的信息,但只能发送呢bytes类型 con.close() server.close()
客户端
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import socket client = socket.socket()#创建客户端 Server_ip = ('192.168.15.79',8080) #设置连接服务器的ip地址和端口 client.connect(Server_ip) #连接服务器 client.send(b'cisoc')#连接完成后向服务端发送信息 cc = client.recv(1024) #设置接收文件的大小 print(cc) client.close()
加强版
服务端
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import socket import time server = socket.socket() ip = ('192.168.15.79',8080) server.bind(ip) server.listen(4) con,addr = server.accept() while 1: Input_server = input('服务器端的消息:').encode('utf-8') con.send(Input_server) resever_msg = con.recv(1024).decode('utf-8') print(resever_msg) a = eval(con.recv(1024).decode('utf-8')) gg = time.localtime(a) print(time.strftime('%Y-%m-%d %H:%M:%S', gg)) if Input_server == 'bye'.encode('utf-8'): break server.close() con.close()
客户端
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import socket import time client = socket.socket() ip = ('192.168.15.79',8080) client.connect(ip) while 1 : Resver_msg = client.recv(1024).decode('utf-8') print(Resver_msg) Input_client = input('客户端输入:').encode('utf-8') Time_Send = str(time.time()).encode('utf-8') client.send(Input_client) client.send(Time_Send) if Input_client == 'bye'.encode('utf-8'): break client.close()
socket类型
socket 方法的详细解析:
import subprocess
#模块的作用是 允许你用一个进程去连接系统的管道,可以接受对应的输入,输出,和错误的结果
简单应用
#模块的作用是
允许你用一个进程去连接系统的管道,可以接受对应的输入,输出,和错误的结果
cmd = input('请输入:')
sub_obj = subprocess.Popen(
cmd,
shell = True,
stdout = subprocess.PIPE,#指令正确的时候的输出结果
stderr = subprocess.PIPE#指令错误的时候输出的结果
)
print(sub_obj.stdout.read().decode('gbk'))
print(sub_obj.stderr.read().decode('gbk'))
import struct
a=12
# 将a变为二进制
bytes=struct.pack('i',a)
-------------------------------------------------------------------------------
struct.pack('i',1111111111111) 如果int类型数据太大会报错struck.error
struct.error: 'i' format requires -2147483648 <= number <= 2147483647 #这个是范围
import sockerserver
import socketserver class server(socketserver.BaseRequestHandler):#创建一个类,继承BaseRequestHandler(这里类基本是空的类,继承后直接改写里面的方法就可以) def handle(self): #改写BaseRequestHandler里面的handle 方法,默认是pass,重写后,由于BaseRequestHandler初始化方法中的 try: self.handle(),所以只要创建server对象 #这里的代码就会执行 self.request.recv(1024) self.request.send(b'jfsof ') ip = ('127.0.0.1',8080) ser = socketserver.ThreadingTCPServer(ip,server)# 创建这个对象的具体作用是 #在这里对象里面创建了一个socket对象,并将对象与ip.port进行了绑定同时还设置了监听的数量为5,将自定义了类名传递给BaseServer,作为了这个类的一个实例变量 ser.serve_forever()#让socket对象一直运行,并开启多线程应对并发,之后BaseServer
通过finish_request方法将自定义类的实例化,就开始了通信的过程
具体的过程
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
在整个socketserver这个模块中,其实就干了两件事情:1、一个是循环建立链接的部分,每个客户链接都可以连接成功 2、一个通讯循环的部分,就是每个客户端链接成功之后,要循环的和客户端进行通信。 看代码中的:server=socketserver.ThreadingTCPServer(('127.0.0.1',8090),MyServer) 还记得面向对象的继承吗?来,大家自己尝试着看看源码: 查找属性的顺序:ThreadingTCPServer->ThreadingMixIn->TCPServer->BaseServer 实例化得到server,先找ThreadMinxIn中的__init__方法,发现没有init方法,然后找类ThreadingTCPServer的__init__,在TCPServer中找到,在里面创建了socket对象,进而执行server_bind(相当于bind),server_active(点进去看执行了listen) 找server下的serve_forever,在BaseServer中找到,进而执行self._handle_request_noblock(),该方法同样是在BaseServer中 执行self._handle_request_noblock()进而执行request, client_address = self.get_request()(就是TCPServer中的self.socket.accept()),然后执行self.process_request(request, client_address) 在ThreadingMixIn中找到process_request,开启多线程应对并发,进而执行process_request_thread,执行self.finish_request(request, client_address) 上述四部分完成了链接循环,本部分开始进入处理通讯部分,在BaseServer中找到finish_request,触发我们自己定义的类的实例化,去找__init__方法,而我们自己定义的类没有该方法,则去它的父类也就是BaseRequestHandler中找.... 源码分析总结: 基于tcp的socketserver我们自己定义的类中的 self.server即套接字对象 self.request即一个链接 self.client_address即客户端地址 基于udp的socketserver我们自己定义的类中的 self.request是一个元组(第一个元素是客户端发来的数据,第二部分是服务端的udp套接字对象),如(b'adsf', <socket.socket fd=200, family=AddressFamily.AF_INET, type=SocketKind.SOCK_DGRAM, proto=0, laddr=('127.0.0.1', 8080)>) self.client_address即客户端地址
socket server
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import socketserver class server(socketserver.BaseRequestHandler): def handle(self): while 1: dd = self.request.recv(1024).decode('utf-8') print('来自%s的消息:%s' % (self.client_address, dd)) gg = input('服务端》》》').encode('utf-8') self.request.send(gg) #self.request >>>> 连接管道 #self.client_address >>>> 客户端地址 ser = socketserver.ThreadingTCPServer(('127.0.0.1',8080),server) ser.serve_forever()
客户端
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import socket cli = socket.socket() cli.connect(('127.0.0.1',8080)) while 1: msg = input('客户端1>>>').encode('utf-8') cli.send(msg) msg_from_server = cli.recv(1024).decode('utf-8') print(msg_from_server)