Python-网络和文件

  • Post author:
  • Post category:python


操作文件和 socket 编程在平时也是必不可少的,这里介绍了 Python3 相关内容,做一个备忘。



网络编程



socket 编程
  • Linux 中的 socket :

    • socket 也叫做套接字,起源于Unix,是应用层与 TCP/IP 协议族通信的中间软件抽象层,它是一组接口;
    • socket 中没有层的概念,它只是一个 facade 设计模式(门面模式)的应用,它把复杂的 TCP/IP 协议族隐藏在 socket 接口后面;对用户来说,一组简单的接口就是全部,让 socket 去组织数据,以符合指定的协议,而不需要让用户自己去定义什么时候需要指定哪个协议哪个函数;
    • socket 都可以用

      open() –> write/read –> close()

      模式来操作,socket 即是一种特殊的文件,一些 socket 函数就是对其进行的操作(读/写IO、打开、关闭);
    • 在网络编程中,我们大量用的都是通过socket实现的。
  • Python 中 socket 函数接口相关:

    • AF_UNIX 代表本地通讯套接字
    • AF_INET 代表 IPV4 网络套接字
    • SOCK_STREAM 代表基于连接的数据传输,类比 TCP
    • SOCK_DGRAM 代表不基于连接,基于报文的数据传输,类比 UDP

    • bind()

      绑定地址时,在 AF_UNIX 下是文件名的形式,在 AF_INET 下是(host,port)的形式

    • listen()

      开始监听绑定的地址,参数含义:在拒绝连接之前,可以挂起的最大连接数量

    • send()

      发送数据

    • recv()

      接收数据
  • C/S 模型示例

# Server 端
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) # 创建套接字对象
sockName = "/tmp/UNIX.motion.server.d"
if os.path.exists(sockName):
    os.unlink(sockName)
s.bind(sockName)  # 绑定地址
s.listen(5)       # 开始监听
conn, address = s.accept() # 被动接受客户端连接,阻塞式等待连接的到来
data = 'hello world'
conn.send(bytes(data, "utf-8")) # 数据交换
conn.close()
s.close()
        
# Client 端
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) # 创建套接字对象
s.connect("/tmp/UNIX.motion.server.d") # 发送连接请求
data = s.recv(500)   # 数据交换
s.close()


SSL(Secure Sockets Layer 安全套接层)
  • python 标准库 ssl 可实现加密通信
  • ssl 库底层使用 openssl,做了面向对像化改造和简化,但还是可以明显看出 openssl 的痕迹
  • 说到 ssl 很多人都会想到https,但本质而言 ssl 是在传输层和应用层之间新插入的一个层,根据不同层无关原则 ssl 和 https 并没有任何绑定关系,ssl 之上完全可以是其他任何应用层协议
  • 应用实例
## 服务端
context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) # 生成 SSL 上下文
context.load_cert_chain('cert/server.crt', 'cert/server_rsa_private.pem.unsecure') # 加载服务器所用证书和私钥
with socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) as sock: # 监听端口
    sock.bind(('127.0.0.1', 9443))
    sock.listen(5)
    # 将 socket 打包成 SSL socket
    with context.wrap_socket(sock, server_side=True) as ssock:
        while True:
            # 接收客户端连接
            client_socket, addr = ssock.accept()
            # 接收客户端信息
            msg = client_socket.recv(1024).decode("utf-8")
            print(f"receive msg from client {addr}:{msg}")
            # 向客户端发送信息
            msg = f"yes , you have client_socketect with server.\r\n".encode("utf-8")
            client_socket.send(msg)
            client_socket.close()

## 客户端
context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) # 生成 SSL 上下文
context.load_verify_locations('cert/ca.crt') # 加载信任根证书
with socket.create_connection(('127.0.0.1', 9443)) as sock: # 与服务端建立 socket 连接
    # 将 socket 打包成 SSL socket
    # 一定要注意的是这里的server_hostname不是指服务端IP,而是指服务端证书中设置的CN
    with context.wrap_socket(sock, server_hostname='127.0.0.1') as ssock:
        # 向服务端发送信息
        msg = "do i connect with server ?".encode("utf-8")
        ssock.send(msg)
        # 接收服务端返回的信息
        msg = ssock.recv(1024).decode("utf-8")
        print(f"receive msg from server : {msg}")
        ssock.close()


文件和 I/O

本文只讨论 Python 的文件和流操作,不讨论系统相关的目录操作。



文件操作常用函数

  • open()

    ,打开文件,文件指针的位置和打开时的读写模式有关

  • .close()

    ,关闭文件,释放文件句柄,建议使用

    with

    操作

  • .write()

    ,以当前文件指针,向文件写数据

  • .read()

    ,以当前文件指针,从文件读数据

  • .readline()

    ,以当前文件指针,从文件读一行文本

  • .tell()

    ,显示当前指针位置

  • .seek()

    ,移动指针位置


文件打开读写模式

  • w

    以写方式打开

  • W

    文件若存在,首先要清空,然后(重新)创建

  • a

    以追加模式打开 (从 EOF 开始, 必要时创建新文件)

  • r+

    以读写模式打开

    1. 文件存在,打开文件,文件指针定位到

    文件开始位置


    2. 文件不存在, 则报错文件不存在。

  • w+

    以写读模式打开 (参见 w )

    1. 文件存在,则

    清空

    (也即写入空);

    2. 文件不存在,则创建文件 ;

    3. 文件流定位到开始位置, 所以read() 会得到空。

  • a+

    以读写模式打开 (参见 a )

    1. 文件存在,打开文件,文件指针定位到文件开始位置,但不清空;

    2. 文件不存在,创建文件;

    3. 打开后读取时,在文件开头位置,

    4. 写入时,添加到文章末尾,并且指针位于添加后的末尾,所以再次读取会乱码。

  • rb

    以二进制读模式打开

  • wb

    以二进制写模式打开 (参见 w )

  • ab

    以二进制追加模式打开 (参见 a )

  • rb+

    以二进制读写模式打开 (参见 r+ )

  • wb+

    以二进制读写模式打开 (参见 w+ )

  • ab+

    以二进制读写模式打开 (参见 a+ )
  • 另外:

    1.

    w

    打开文件写入,也会清空文件,如果使用read(),则报错;a 打开文件添加,数据流添加到文件末尾,而不是w模式的清空后,添加到文件末尾。

    2.

    b

    可以附加到上述的字母后,形成

    rb

    ,

    rb+

    ,

    wb

    等等模式,针对二进制文件,比如exe, elf, jpeg格式的文件,进行文件操作; 在unix 类型的系统上,text格式与二进制的处理相同,但是非unix类型的系统上,换行格式不同,所以需要用加b模式来在指定是否是二进制。


    1. 并发读文件时

      ,偶尔会因为读不到(其实有数据)数据而返回 ‘’ 空串,应该是因为句柄被占用了。


I/O 流操作

io 模块提供了 Python 用于处理各种 I/O 类型的主要工具。三种主要的 I/O 类型分别为: 文本 I/O, 二进制 I/O 和原始 I/O。这些是泛型类型,有很多种后端存储可以用在他们上面。一个隶属于任何这些类型的具 体对象被称作 file object。其他同类的术语还有 流和 类文件对象。

  • Text I/O 用于识别和处理字符串你对象。
  • Binary I/O 也称作缓冲流,以字节为对象操作数据。
  • Raw I/O 也称作非缓冲流,用于低级别的的二进制流操作。


参考文档


https://blog.csdn.net/vic_qxz/article/details/83934989



版权声明:本文为ManWZD原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。