网络编程之模块的使用

socket模块的使用

1.模仿CS 架构模型

1.1简版

服务器端

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()
View Code

客户端

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()
View Code

加强版

服务端

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()
View Code

客户端

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()
View Code

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方法将自定义类的实例化,就开始了通信的过程

 具体的过程

在整个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即客户端地址
View Code

 socket server

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()
View Code

客户端

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)
View Code

 

原文地址:https://www.cnblogs.com/vivi0403/p/9995952.html