创建套接字
socket()函数
socket(socket_family,socket_type,protocol=0)
#socket_family 是AF_INET或AF_UNIX
#socket_type 套接字类型SOCK_STREAM(TCP类型)或SOCK_DGRAM(UDP类型)
#protocol通常省略,默认为0
创建TCP套接字
tcpSerSock = socket(AF_INET, SOCK_STREAM)
创建UDP套接字
tcpSerSock = socket(AF_INET, SOCK_DGRAM)
常见的套接字对象方法和属性
服务器套接字方法
名称 | 描述 |
---|---|
s.bind() | 将地址(主机号,端口号对)绑定在套接字上 |
s.listen() | 设置并启动TCP监听器 |
s.accept() | 被动接受TCP客户端连接,一直等待直到连接到达 |
客户端套接字方法
名称 | 描述 |
---|---|
s.connect() | 主动发起TCP服务器连接 |
s.connect_ex | connect()的扩展版本,此时会以错误码的形式返回问题,而不是抛出一个异常 |
普通的套接字方法
名称 | 描述 |
---|---|
s.recv() | 接受TCP消息 |
s.recv_into() | 接受TCP消息到指定的缓冲区 |
s.send() | 发送TCP消息 |
s.sendall() | 完整的发送TCP消息 |
s.recvfrom() | 接受UDP消息 |
s.recvfrom_into() | 接受UDP消息到指定缓冲区 |
s.sendto() | 发送UDP消息 |
s.getpeername() | 连接到套接字(TCP)的远程地址 |
s.getsockname() | 当前套接字地址 |
s.getsockopt() | 返回给定套接字选项的值 |
s.setsockopt() | 设置给定套接字选项的值 |
s.shutdown() | 关闭连接 |
s.close() | 关闭套接字 |
s.detach() | 在未关闭文件描述符的情况下关闭套接字,返回文件描述符 |
s.ioctl() | 控制套接字的模式(仅window) |
面向阻塞的套接字方法
名称 | 描述 |
---|---|
s.setblocking() | 设置套接字的阻塞或非阻塞模式 |
s.settimeout() | 设置阻塞套接字操作的超时时间 |
s.gettimeout() | 获取阻塞套接字操作的超时时间 |
面向文件的套接字方法
名称 | 描述 |
---|---|
s.fileno() | 套接字的文件描述符 |
s.makefile() | 创建与套接字相关的文件对象 |
数据属性
名称 | 描述 |
---|---|
s.family | 套接字家族 |
s.type | 套接字类型 |
s.proto | 套接字协议 |
TCP服务端
这是一个时间戳服务器,客户端发送消息,服务端接受到之后打上一个时间戳然后返回信息。
参考《Python核心编程》,里面的测试有一些报错,下面是调整之后的程序
伪码
ss = socket() # 创建服务器套接字
ss.bind() # 套接字与地址绑定
ss.listen() # 监听连接
inf_loop: # 服务器无限循环
cs = ss.accept() # 接受客户端连接
comm_loop: # 通信循环
cs.recv()/cs.send() # 对话(接收/发送)
cs.close() # 关闭客户端套接字
ss.close() # 关闭服务器套接字#(可选)
具体实现
[root@localhost ~]# cat tcpserv.py
#!/usr/bin/env python3.4
from socket import * #socket模块不需要下载,自带了
from time import ctime
HOST = ''
PORT = 21567
BUFSIZE = 1024
ADDR = (HOST, PORT)
tcpSerSock = socket(AF_INET, SOCK_STREAM) #创建TCP套接字
tcpSerSock.bind(ADDR) #将地址绑定在套接字上
tcpSerSock.listen(5) #设置并监听地址
while True:
print('waiting for connection...')
tcpCliSock, addr = tcpSerSock.accept() #被动接受 TCP 客户端连接,一直等待直到连接到达(阻塞)
print('...connected from:', addr)
while True:
data = tcpCliSock.recv(BUFSIZE).decode() #接受TCP消息
if not data:
break
tcpCliSock.send(('[%s] %s' % (ctime(), data)).encode()) #发送TCP消息
tcpSerSock.close() #关闭套接字
TCP客户端
伪码
cs = socket() # 创建客户端套接字
cs.connect() # 尝试连接服务器
comm_loop: # 通信循环
cs.send()/cs.recv() # 对话(发送/接收)
cs.close() # 关闭客户端套接字
具体实现
[root@localhost ~]# cat tcpcli.py
#!/usr/bin/env python3.4
from socket import *
#地址要和服务端相同
HOST = '127.0.0.1'
PORT = 21567
BUFSIZE = 1024
ADDR = (HOST, PORT)
tcpCliSock = socket(AF_INET, SOCK_STREAM) #创建TCP套接字
tcpCliSock.connect(ADDR) #主动发起TCP服务器连接
while True:
data = input('> ')
if not data:
break
tcpCliSock.send(data.encode()) #发送TCP消息
data = tcpCliSock.recv(BUFSIZE).decode() #接受TCP消息
if not data:
break
print(data)
tcpCliSock.close()
先启动服务端,然后启动客户端
客户端
服务端