Socket介绍
在网络上两个程序通过一个双向的通信连接实现数据交换,这个链接的一端称为一个Socket(套接字),用于描述IP地址和端口。
建立网络通信连接至少要有一对端口号(socket),Socket本质是API,对于TCP/IP的封装提供网络通信能力。
每一种服务都打开一个socket并绑定在端口上,不同端口对应不同服务。
Socket是面向C/S模型设计的,客户端在本地随机申请一个唯一的socket号,服务器拥有公开的socket,任何客户端口可以向它发起连接请求和信息请求。
Python中使用的socket和SocketServer模块
socket模块
Method | Description |
---|---|
socket.socket([family[,type[,proto]]]) | socket初始化函数(地址族,socket类型,协议号默认为0) |
socket.AF_INET | IPV4协议通信 |
socket.AF_INET6 | IPV6协议通信 |
socket.SOCK_STREAM | socket类型,TCP |
socket.SOCK_DGRAM | socket类型,UDP |
socket.SOCK_RAW | 原始socket,可以处理普通socket无法处理的报文,比如icmp |
socket.SOCK_RDM | 更可靠的UDP类型,保证对方能获取到数据 |
socket.SOCK_SEQPACKET | 可靠的连续数据包服务 |
socket.socket()对象有以下方法:
accept() | 接受连接并返回(socket object, address info), address是客户端地址 |
---|---|
bind(address) | 绑定socket到本地地址,address是一个双元素元组(host, port) |
listen(backlog) | 开始接收连接,backlog最大连接数为1 |
connect(address) | 连接socket到远程地址 |
connect_ex(address) | 连接socket到远程地址,成功返回0,错误返回error值 |
getpeername() | 返回远端地址(hostaddr, port) |
gettimeout() | 返回当前超时的值,单位为秒,如果没有设置返回None |
rercv(buffersize[, flags]) | 接收来自socket的数据,buffersize是接收数据量 |
send(data[, flags]) | 发送数据到socket,返回值是发送的字节数 |
sendall(data[, flags]) | 发送所有数据到socket,成功返回None,失败返回异常 |
setblocking(flags) | 设置socket为阻塞(flag=true)或者非阻塞(flag=false) |
TCP编程
我们编写了一个socket_server_tcp.py作为服务器接收并返回数据,以及socket_client_tcp.py作为客户端发送数据给服务器端并接收返回来的数据,
socket服务器端的工作步骤如下:
- 打开socket
- 绑定到一个地址和端口
- 监听进来的连接
- 接受连接
- 处理数据
UDP编程
可以查看代码socket_server_udp.py和socket_client_udp.py。
与TCP不同的是,UDP的服务器端缺少了listen()和accept(),不需要建立连接就可以把数据直接发送给客户端; 同时客户端少了connect(),同样直接通过sendto()给服务器发送数据。
客户端发送bash命令,然后在服务器端执行
可以查看代码bash_socket_server.py和bash_socket_client.py
SocketServer
SocketServer是socket服务端库, 实现多线程, 并法处理客户端请求.
|:–|:–|
|SocketServer.TCPServer(server_address, RequestHandlerClass, bind_and_activate=True)|服务器类, TCP协议|
|SocketServer.UDPServer(server_address, RequestHandlerClass, bind_and_activate=True)|服务器类, UDP协议|
|SocketServer.BaseServer(server_address, RequestHandlerClass)|这个是所有服务器对象的超类,定义了接口,不提供大多数方法|
|SocketServer.BaseRequestHandler|所有请求处理对象的超类, 定义了接口, 一个具体的请求处理程序子类必须定义一个新的handler()方法|
|SocketServer.StreamRequestHandler|流式socket, 根据socket生成读写socket用的两个文件对象, 调用rfile和wfile读写|
|SocketServer.DatagramRequestHandler|数据报socket,同样生成rfile和wfile,但是UDP不直接关联socket.rfile是由UDP中读取的数据生成的,wfile是新建一个StringIO,用于写数据|
|SocketServer.ForkingMixIn/ThreadingMixIn|多进程(分叉)多线程实现异步. 混合类, 这个类不会直接实例化. 用于实现处理多连接|