18 网络编程
本章节转载自Python之路【第六篇】:socket
socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求。
socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,对于文件用【打开】【读写】【关闭】模式来操作。socket就是该模式的一个实现,socket即是一种特殊的文件,一些socket函数就是对其进行的操作(读/写IO、打开、关闭)
- file模块是针对某个指定文件进行【打开】【读写】【关闭】
- socket模块是针对 服务器端 和 客户端Socket 进行【打开】【读写】【关闭】

sk = socket.socket(socket.AF_INET,socket.SOCK_STREAM,0)
- 参数一:地址簇(地址家族)
- socket.AF_INET :IPv4(默认)
- socket.AF_INET6 : IPv6
- socket.AF_UNIX :只能够用于单一的Unix系统进程间通信
- 参数二:类型
- socket.SOCK_STREAM:流式socket , for TCP (默认)
- socket.SOCK_DGRAM:数据报式socket , for UDP
- socket.SOCK_RAW:原始套接字,普通的套接字无法处理ICMP、IGMP等网络报文,而SOCK_RAW可以;其次,SOCK_RAW也可以处理特殊的IPv4报文;此外,利用原始套接字,可以通过IP_HDRINCL套接字选项由用户构造IP头。
- socket.SOCK_RDM:是一种可靠的UDP形式,即保证交付数据报但不保证顺序。SOCK_RAM用来提供对原始协议的低级访问,在需要执行某些特殊操作时使用,如发送ICMP报文。SOCK_RAM通常仅限于高级用户或管理员运行的程序使用。
- socket.SOCK_SEQPACKET:可靠的连续数据包服务
- 参数三:协议
- 0 (默认)与特定的地址家族相关的协议,如果是 0 ,则系统就会根据地址格式和套接类别,自动选择一个合适的协议
sk.bind(address)
s.bind(address) 将套接字绑定到地址。address地址的格式取决于地址族。在AF_INET下,以元组(host,port)的形式表示地址。一般用于server端
sk.listen(backlog)
开始监听传入连接。backlog指定在拒绝连接之前,可以挂起的最大连接数量。例如:backlog等于5,表示内核已经接到了连接请求,但服务器还没有调用accept进行处理的连接个数最大为5。这个值不能无限大,因为要在内核中维护连接队列。一般用于server端
sk.accept()
以阻塞的形式,接受client连接,并返回(conn,address)。其中conn是新的套接字对象,可以用来接收和发送数据;address是连接客户端的地址。
总结:接收TCP 客户的连接(阻塞式)等待连接的到来。
sk.connect(address)
连接到address处的套接字。一般,address的格式为元组(hostname,port),如果连接出错,返回socket.error错误。与sk.accept()成对出现。一般用于client端。
sk.sendall(string[,flag])
将string中的数据发送到连接的套接字,但在返回之前会尝试发送所有数据。成功返回None,失败则抛出异常。
内部通过递归调用send,将所有内容发送出去。
sk.recv(bufsize[,flag])
接受套接字的数据。数据以字符串形式返回,bufsize指定最多可以接收的数量。flag提供有关消息的其他信息,通常可以忽略。
server端:
import socket
sk=socket.socket() #创建套接字对象
sk.bind(('127.0.0.1',9999,)) #套接字绑定ip:port
sk.listen(5) #监听套接字,数字代表最大并发请求数
while True:
conn,address=sk.accept() #接受来自其他套接字发来的连接请求,返回一个新的套接字对象(含有remote address信息,可以理解为是个请求连接对象)和客户端address信息,accept方法会阻塞。
conn.sendall(bytes('welcome',encoding='utf-8'))
while True:
ret=str(conn.recv(1024),encoding='utf-8')
if ret== 'q':
break
else:
conn.sendall(bytes(ret+"OK",encoding='utf-8'))
client端:
import socket
obj=socket.socket() #创建套接字
obj.connect(('127.0.0.1',9999)) #连接到其他套接字(发送连接请求),远端socket.accept()接受连接请求
ret_bytes=obj.recv(1024) #接受1024字节,返回结果为字节码,recv方法会阻塞
ret_str=str(ret_bytes,encoding='utf -8')
print(ret_str)
print('1111')
while True:
inp=input("请输入内容:")
obj.sendall(bytes(inp,encoding='utf-8'))
ret=str(obj.recv(1024),encoding='utf-8')
print(ret)
obj.close()
Python中有一个select模块,其中提供了:select、poll、epoll三个方法,分别调用系统的 select,poll,epoll 从而实现IO多路复用。
Windows Python:
提供: select
Mac Python:
提供: select
Linux Python:
提供: select、poll、epoll