十三.网络编程

1.socket套接字的原理和应用

  • 简单的server1和client1
    #服务器与客户端建立方式不同
    #网络连接的主要操作就是接受recv和发送send,python3里网络传输只能用byte
    #recv(128)表示一次传输的最大容量,如果传输的内容过大,需要多次recv(128)才可以接受完。即使过大,每次不一定按照128进行最大传输
    import socket
    s=socket.socket() #建立一个套接字网络单位
    #网络连接的host名称和端口需要一致才可以
    host=socket.gethostname()
    port=1234
    s.bind((host,port)) #bind绑定,说明这是服务器
    #最多监听的客户端数量
    s.listen(5)
    while True:
        #一个网络单位(服务器)可以有多个客户端连接
        c,addr=s.accept() #这是客户端连接时才执行,返回连接和地址
        data = c.recv(1024)  #服务器连接后接受到的客户端内容
        print("server get data:",data)
        print("Got connection from",addr)
        #服务器两次发送信息,客户端也需要两次接受
        c.send("Thank you for connecting".encode()) #str需要转成比特
        c.send(data) #发送接受到的信息,原本就是byte
        c.close()
    #---------------------------------------------------------------------------------
    import socket
    s=socket.socket() #建立一个套接字网络单位
    # host=socket.gethostname()
    # port=1234
    host=socket.gethostname()
    port=1234
    #s网络单位进行connect连接,说明这是客户端
    s.connect((host,port))
    #向服务器发送信息,需要变成byte
    s.send("This is client".encode())
    #由于客户端发送了两次信息,需要两次接受
    print(s.recv(1024).decode()) #把比特数据转成str
    print(s.recv(1024).decode()) #把比特数据转成str
    print(s.recv(1024).decode()) #把比特数据转成str
    print(s.recv(1024).decode()) #把比特数据转成str
  • 简单的server2和client2
    import socket ,os,time
    server = socket.socket()
    server.bind(('localhost',9999) )
    server.listen()
    
    while True:
        conn, addr = server.accept()
        print("new conn:",addr)
        while True:
            print("等待新指令")
            # recv(128)表示一次传输的最大容量,如果传输的内容过大,需要多次recv(128)才可以接受完
            data = conn.recv(128)
            if not data:
                print("客户端已断开")
                break
            print("执行指令:",data)
            cmd_res = os.popen(data.decode()).read() #接受字符串,执行结果也是字符串
            print("before send",len(cmd_res))
            if len(cmd_res) ==0:
                cmd_res = "cmd has no output..."
            # 先发内容的byte大小给客户端,用于处理传输内容大于通道时的情况
            conn.send( str(len(cmd_res.encode())).encode("utf-8")    )
            time.sleep(0.5)
            conn.send(cmd_res.encode("utf-8"))
            print("send done")
            # os.path.isfile()
            # os.stat("sock")
    server.close()
    #---------------------------------------------------------------------------------
    import socket
    client = socket.socket()
    #client.connect(('192.168.16.200',9999))
    client.connect(('localhost',9999))
    while True:
        cmd = input(">>:").strip()
        if len(cmd) == 0: continue
        client.send(cmd.encode("utf-8"))
        ##第一次接受内容命令结果的长度,byte数据
        cmd_res_size = client.recv(128)
        print("命令结果大小:",cmd_res_size)
        received_size = 0
        received_data = b''
        TotalSize=int(cmd_res_size.decode()) #byte数据转成整数
        #开始接受内容
        while received_size < TotalSize :
            data = client.recv(128)
            # 每次收到的有可能小于1024,所以必须用len判断,返回的是byte长度
            received_size += len(data)
            print("接受内容的长度:",len(data))
            #print("接受的内容:",data) #分段打印有时候打印不出来,因为分段格式有时不完整
            received_data += data
        else:
            print("cmd res receive done...",received_size)
            print(received_data.decode())
    client.close()
    server2 and client2
  • 结合select的服务器
    import socket,select
    s=socket.socket()
    host=socket.gethostname()
    port=1234
    s.bind((host,port))
    s.listen(5)
    Inputs=[s]
    while True:
        rs,ws,es=select.select(Inputs,[],[])
        for r in rs:
            if r is s:
                conn,addr=s.accept()
                print("Got Connection From",addr)
                Inputs.append(conn)
        else:
            try:
                data=r.recv(1024)
                disconnected=not data
            except socket.error:
                disconnected=True
            if disconnected:
                print(r.getpeername(),"disconnected")
                Inputs.remove(r)
            else:
                print(data)
    socket and select

2.读取网站

import urllib.request as class_url
#返回一个可以读取的对象
webaddress="http://www.python.org"
webpage=class_url.urlopen(webaddress)
import re
text=webpage.read()
m=re.search(b'<a href="([^"]+)" .*?>about</a>',text,re.IGNORECASE) #正则表达式
print(m.group())
#获取远程文件
class_url.urlretrieve(webaddress,"download.html")
#class_url.urlcleanup() #上面不指定位置才需要用
urllib.request

3.可并发的socketserver服务器

可并发的服务器
原文地址:https://www.cnblogs.com/i201102053/p/10675457.html