0%

python技巧(1)

[TOC]

套接字

Socket:对于网络通信而言,套接字是一个通用的网络编程接口,用于不同主机的进程之间来通信,每一个socket都可用网络地址结构(协议、本地地址、本地端口)来表示。

分类:

  • 流式套接字(SOCK_STREAM):提供面向连接、可靠的数据传输服务,数据无差错、无重复的发送且按发送顺序接收。内设置流量控制,避免数据流淹没慢的接收方。数据被看作是字节流,无长度限制。TCP通信使用的就是流式套接字。
  • 数据报套接字(SOCK_DGRAM):提供无连接服务。数据包以独立数据包的形式被发送,不提供无差错保证,数据可能丢失或重复,顺序发送,可能乱序接收。UDP通信使用的就是数据报套接字。
  • 原始套接字(SOCK_RAW):原始套接字允许对较低层次协议如IP、ICMP进行直接访问。它功能强大但使用较为不便,主要用于一些协议的开发。

python Socket包

参考

这里着重介绍今天要用到的:

  • socket.AF_INET:服务器之间网络通信
  • socket.SOCK_STREAM:流式socket , for TCP

由此,创建一个TCP Socket: s=socket.socket(family = socket.AF_INET,type = socket.SOCK_STREAM)

客户端socket函数:

s.connect(address):连接到address处的套接字。一般address的格式为元组(hostname,port),如果连接出错,返回socket.error错误。

让对象支持上下文管理器

为了让对象支持上下文管理器,需要实现

1
__enter__() 和 __exit__()两个方法

代码:

这里注意观察注释掉的代码和新的代码的不同。注释掉的代码一次只允许创建一个socket连接,而新的代码允许同时存在多个socket连接。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#author:GuiYoung
#desc:class to create web connection
#data 2021/9/7
#lazy_connection.py

from socket import socket, AF_INET, SOCK_STREAM

class LazyConnection:
def __init__(self, address, family=AF_INET, type=SOCK_STREAM):
self.address = address
self.family = AF_INET
self.type = SOCK_STREAM
#self.sock = None
self.connections = []

def __enter__(self):
# if self.sock is not None:
# raise RuntimeError('Already connected')
# self.sock = socket(self.family, self.type)
# self.sock.connect(self.address)
# return self.sock
sock = socket(self.family, self.type)
sock.connect(self.address)
self.connections.append(sock)
return sock

def __exit__(self, exc_type, exc_val, exc_tb):
# self.sock.close()
# self.sock = None
self.connections.pop().close()
1
2
3
4
5
6
7
8
#main.py
import lazy_connection

connection = lazy_connection.LazyConnection('https://www.baidu.com/',80)
with connection as conn1:
...
with connection as conn2:
...