参考:https://gist.github.com/kevinkindom/108ffd675cb9253f8f71
python提供了两个socket模块:
- Socket:提供标准的BSD Socket API
- SocketServer:提供服务器中心,可简化网络服务器开发
这里主要学习Socket模块。
创建Socket
格式:socket(family, type[,protocal])
使用给定套接族,套接字类型,协议编号(默认为0)创建套接字
socket 类型 | 描述 |
---|---|
socket.AF_UNIX | 用于同一台机器上的进程通信(既本机通信) |
socket.AF_INET | 用于服务器与服务器之间的网络通信 |
socket.AF_INET6 | 基于IPV6方式的服务器与服务器之间的网络通信 |
socket.SOCK_STREAM | 基于TCP的流式socket通信 |
socket.SOCK_DGRAM | 基于UDP的数据报式socket通信 |
例:
1 | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) |
Socket函数
TCP发送数据时,已建立好TCP链接,所以不需要指定地址,而UDP是面向无连接的,每次发送都需要指定发送给谁。服务器与客户端发送的数据是字符串。
服务器端 Socket 函数
Socket 函数 | 描述 |
---|---|
s.bind(address) | 将套接字绑定到地址,在AF_INET下,以tuple(host, port)的方式传入,如s.bind((host, port)) |
s.listen(backlog) | 开始监听TCP传入连接,backlog指定在拒绝链接前,操作系统可以挂起的最大连接数,该值最少为1,大部分应用程序设为5 |
s.accept() | 接受TCP链接并返回(conn, address),其中conn是新的套接字对象,可以用来接收和发送数据,address是链接客户端的地址。 |
客户端 Socket 函数
Socket 函数 | 描述 |
---|---|
s.connect(address) | 链接到address处的套接字,一般address的格式为tuple(host, port),如果链接出错,则返回socket.error错误 |
公共 Socket 函数
Socket 函数 | 描述 |
---|---|
s.recv(bufsize[, flag]) | 接受TCP套接字的数据,数据以字符串形式返回,buffsize指定要接受的最大数据量,flag提供有关消息的其他信息,通常可以忽略 |
s.send(string[, flag]) | 发送TCP数据,将字符串中的数据发送到链接的套接字,返回值是要发送的字节数量,该数量可能小于string的字节大小 |
s.settimeout(timeout) | 设置套接字操作的超时时间,timeout是一个浮点数,单位是秒,值为None则表示永远不会超时。一般超时期应在刚创建套接字时设置,因为他们可能用于连接的操作,如s.connect() |
s.recvfrom(bufsize[, flag]) | 接受UDP套接字的数据u,与recv()类似,但返回值是tuple(data, address)。其中data是包含接受数据的字符串,address是发送数据的套接字地址 |
s.sendto(string[, flag], address) | 发送UDP数据,将数据发送到套接字,address形式为tuple(ipaddr, port),指定远程地址发送,返回值是发送的字节数 |
s.close() | 关闭套接字 |
步骤
TCP 服务器
1、创建套接字,绑定套接字到本地IP与端口
1 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) |
2、开始监听链接
1 | s.listen() |
3、进入循环,不断接受客户端的链接请求
1 | While True: |
4、接收客户端传来的数据,并且发送给对方发送数据
1 | s.recv() |
5、传输完毕后,关闭套接字
1 | s.close() |
TCP 客户端
1、创建套接字并链接至远端地址
1 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) |
2、链接后发送数据和接收数据
1 | s.sendall() |
3、传输完毕后,关闭套接字
实例
Socket 编程实践之服务器端代码
1 | import socket |
Socket 编程实践之客户端代码
1 | import socket |
附
编程时一定要注意编码方式啊……比如下面:
1 | print(u'q' == b'q') |
结果为False。
本来想当输入“q”时就断开TCP连接,结果因为编码不同,一直没跳出循环,导致了报错。
u/U:表示unicode字符串
r/R:非转义的原始字符串
在python中交换两个列表:
如大小相等的2个列表a, b,交换这两个列表的内容:
1 | a, b = b, a |
也等同于:
1 | mid = a |