• 25 python 初学(socket,socketserver)


    参考blog :www.cnblogs.com/yuanchenqi/articles/5692716.html

    1. sk = socket.socket()

    里面有两个重要的参数,family type

    type

    SOCK_STREAM : tcp 默认

    SOCK_DGRAM :udp

    family

    family = AF_INET : 服务器之间的通信(默认)

    family = AF_INET6 : 服务器之间的通信

    family=AF_UNIXunix不同进程间通信

    server 下的方法:

    bind()  、 listen()  、 accept()

    recv()  、 send()  、 sendall()

    close()

    client 下的方法:

    connect()

    recv() 、send( string ) 、sendall()  # 传送的类型一定是 byte 类型

    close()

     

    # _author: lily
    # _date: 2019/1/25
    
    #  server 端
    
    import socket
    
    sk = socket.socket()
    address = ('127.0.0.1', 8000)
    sk.bind(address)
    sk.listen(3)
    print('waiting')
    # print(sk)
    conn, address_client = sk.accept()
    
    while 1:
        send_data = input('input>>')
        if send_data == 'exit':
            break
        conn.send(bytes(send_data, 'utf8'))
        rec_data = conn.recv(1024)
        print(str(rec_data, 'utf8'))
    
    conn.close()

     

    # _author: lily
    # _date: 2019/1/25
    
    # client 端
    
    import socket
    sk = socket.socket()
    # print(sk)
    
    adress = ('127.0.0.1', 8000)
    sk.connect(adress)
    
    while 1:
        rec_data = sk.recv(1024)  # 会阻塞,直到收到数据
        if not rec_data:
            break
        print(str(rec_data, 'utf8'))
        send_data = input('>>')
        sk.send(bytes(send_data, 'utf8'))
    
    sk.close()

    socket 流程:

    1. 先开启服务端,bind 绑定ip 和端口;

    2. 其次 listen 监听,里面的数字表示有多少客户端可排队(不包括当前正在通信的,排队表示可连接但是不能通信。比如设定上限为3,当第四个客户端来连接时就会报错无法连接)

    3. 接着需要 accept(),阻塞等待连接。accept 接受到的值是对方的 sk,进行连接(相当于两端建立了一个通道,server client 都使用的这个通道,只是各自的命名不同)。

    4. 保证一收一发原则

    5. 关闭时关闭这个通道。 conn.close() 

    1. 客户端进行连接,先创建一个socket 对象 sk

    2. sk 使用 connect 连接服务端

    3. 保证一收一发原则

    4. 关闭时 sk.close()

     

    粘包现象的解决办法:

    加一个 conn.recv1024) 进行阻塞,将两个连续的conn.send()分隔开

     

    编码拾遗:

    • strunicode
    • bytes:十六进制
    • str -> bytes:编码

        s = hello 你好

        b = bytes(s, utf8)

        b2 = s.encode(utf8)    #  两个是一样的

    • bytes -> str:解码

        s2 = str(b2, utf8)

        s2 = b2.decode(utf8)

     

    socketserver

    1. 调用模块

    2. 自己写一个类,继承 socketserver.BaseRequestHandler,并重写 handle()方法

    3. main 方法内:

               调用 socketserver.ThreadingTCPServer,创建一个实例 

     

    # _author: lily
    # _date: 2019/1/28
    # Server 端
    
    import socketserver
    
    class myserver(socketserver.BaseRequestHandler):
        # 主要逻辑
        def handle(self):
            print('server starting...')
            while True:
                conn = self.request
                print(self.client_address)
                while True:
                    client_data = conn.recv(1024)
                    print(str(client_data, 'utf8'))
                    print('waiting')
                    send_data = input('input>>')
                    conn.sendall(bytes(send_data, 'utf8'))
                    # conn.sendall(client_data)
                conn.close()
    
    if __name__ == '__main__':
        server = socketserver.ThreadingTCPServer(('127.0.0.1', 8091), myserver)
        server.serve_forever()

     

    # _author: lily
    # _date: 2019/1/28
    # client 端
    
    import socket
    
    address = ('127.0.0.1', 8091)
    sk = socket.socket()
    sk.connect(address)
    print('client starting...')
    
    while True:
        data = input('input>>')
        sk.sendall(bytes(data, 'utf8'))
        recv_data = sk.recv(1024)
        print(str(recv_data, 'utf8'))
    
    sk.close()

    实例:

    cmd 命令:

        server 端:

    # _author: lily
    # _date: 2019/1/26
    
    import socket
    import subprocess
    
    sk = socket.socket()
    address = ('127.0.0.1', 8000)
    sk.bind(address)
    sk.listen(3)
    print('waiting')
    # print(sk)
    conn, address_client = sk.accept()
    
    while 1:
    
        try:
            rec_data = conn.recv(1024)
        except Exception:
            break
        if not rec_data:
            break
        print('--client message--', str(rec_data, 'utf8'))
    
        a = subprocess.Popen(str(rec_data, 'utf8'), shell=True, stdout=subprocess.PIPE)
        cmd_result = a.stdout.read()
        result_len = bytes(str(len(cmd_result)), 'utf8')
        conn.sendall(result_len)
        conn.recv(1024)
        conn.sendall(cmd_result)
    
        # send_data = input('input>>')
        # conn.send(bytes(send_data, 'utf8'))
    
    conn.close()
    View Code

        client 端:

    # _author: lily
    # _date: 2019/1/26
    
    import socket
    sk = socket.socket()
    # print(sk)
    
    adress = ('127.0.0.1', 8000)
    sk.connect(adress)
    
    while 1:
    
        send_data = input('>>')
        if send_data == 'exit':
            break
        sk.send(bytes(send_data, 'utf8'))
    
        result_len = int(str(sk.recv(1024), 'utf8'))
        print(result_len)
        rec_data = bytes()
        sk.sendall(bytes('ok', 'utf8'))
        while len(rec_data) != result_len:
            rec_data += sk.recv(1024)  # 会阻塞,直到收到数据
        print(str(rec_data, 'gbk'))
    
    sk.close()
    View Code

    ftp 传输:

        server 端:

    # _author: lily
    # _date: 2019/1/27
    
    import socket
    import subprocess
    import os
    
    sk = socket.socket()
    address = ('127.0.0.1', 8000)
    sk.bind(address)
    sk.listen(3)
    print('waiting')
    BASE_DIR = os.path.dirname(os.path.abspath(__file__))
    
    while 1:
        conn, address_client = sk.accept()
        while 1:
            data = conn.recv(1024)
            cmd, filename, filesize = str(data, 'utf8').split('|')
            path = os.path.join(BASE_DIR, 'picture', filename)
            filesize = int(filesize)
    
            f = open(path, 'ab')
    
            has_receive = 0
            while has_receive != filesize:
                data = conn.recv(1024)
                f.write(data)
                has_receive += len(data)
            f.close()
    
    
    
    conn.close()
    View Code

        client 端:

    # _author: lily
    # _date: 2019/1/27
    
    import socket
    import os
    sk = socket.socket()
    BASE_DIR = os.path.dirname(os.path.abspath(__file__))
    
    adress = ('127.0.0.1', 8000)
    sk.connect(adress)
    
    while 1:
    
        send_data = input('>>').strip()   # post|11.png
        cmd, path = send_data.split('|')
        path = os.path.join(BASE_DIR, path)
    
        filename = os.path.basename(path)
        file_size = os.stat(path).st_size
    
        file_info = 'post|%s|%s' % (filename, file_size)
        sk.sendall(bytes(file_info, 'utf8'))
    
        f = open(filename, 'rb')
        has_sent = 0
        while has_sent != file_size:
            data = f.read(1024)
            sk.sendall(data)
            has_sent += len(data)
        f.close()
        print('success')
    
    sk.close()
    View Code

     

     

    server 下的方法:

    bind()

    listen()

    accept()

     

    recv()

    send( string )

    sendall()

     

    close()

     

     

    client 下的方法:

    connect()

     

    recv()

    send( string )

    sendall()  # 传送的类型一定是 byte 类型

     

    close()

    猪猪侠要努力呀!
  • 相关阅读:
    作业:利用正则表达式知识, 编辑一个简单的表达式计算器
    正则表达式:内置re模块
    HTML5笔记
    安卓开发-intent在Activity之间数据传递
    NumPy-矩阵部分
    Jupyter notebook入门
    Anaconda入门教程
    在python2里面使用python3的print
    判断浏览器是不是支持html5
    python爬虫-html解析器beautifulsoup
  • 原文地址:https://www.cnblogs.com/mlllily/p/10336535.html
Copyright © 2020-2023  润新知