网络编程
名称 | 描 述 |
---|---|
服务器套接字方法 | |
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() | 控制套接字的模式(仅支持Windows)面向阻塞的套接字方法 |
s.setblocking() | 设置套接字的阻塞或非阻塞模式 |
s.settimeout() | 设置阻塞套接字操作的超时时间 |
s.gettimeout() | 获取阻塞套接字操作的超时时间 |
面向文件的套接字方法 | |
s.fileno() | 套接字的文件描述符 |
s.makefile() | 创建与套接字关联的文件对象 |
数据属性 | |
s.family | 套接字家族 |
s.type | 套接字类型 |
s.proto | 套接字协议 |
简单socket通信示例
TCP
书上的例子错误百出, 有毒
服务端:
from socket import *
from time import ctime
HOST = '' # 空白或None表示可使用任何可获取的HOST
PORT = 21414
BUFFSIZ = 1024
ADDR = (HOST, PORT)
s = socket(AF_INET, SOCK_STREAM)
s.bind(ADDR)
s.listen(5) # 传入链接最大数是5
while True:
print('waiting...')
c, addr = s.accept() # accept返回一个可供传输数据的套接字, 和另一端的地址
with c:
print('connected from:', addr)
while True:
data = c.recv(BUFFSIZ)
print('recv: ', data.decode('utf-8'))
if not data:
break
c.send(bytes('[{}] {}'.format(ctime(), data.decode('utf-8')), 'utf-8'))
s.close()
客户端:
from socket import *
HOST = 'localhost'
PORT = 21414
BUFFSIZ = 1024
ADDR = (HOST, PORT)
c = socket(AF_INET, SOCK_STREAM)
c.connect(ADDR)
while True:
data = input('> ')
if not data:
break
c.send(bytes(data, 'utf-8'))
data = c.recv(BUFFSIZ)
if not data:
break
print(data.decode('utf-8'))
c.close()
UDP
服务端:
from socket import *
from time import ctime
host = ''
port = 1234
bufsiz = 1024
addr = (host, port)
s = socket(AF_INET, SOCK_DGRAM)
s.bind(addr)
while True:
print('waiting...')
data, c_addr = s.recvfrom(bufsiz)
s.sendto(
bytes( '[{0}] {1}'.format(ctime(), data.decode('utf-8')), 'utf-8'),
c_addr
)
print('received from {0} : {1}'.format(c_addr, data.decode('utf-8')))
s.close()
客户端:
from socket import *
host = 'localhost'
port = 1234
addr = (host, port)
bufsiz = 1024
c = socket(AF_INET, SOCK_DGRAM)
while True:
data = input('> ')
if not data: break
c.sendto(bytes(data, 'utf-8'), addr)
data, s_addr = c.recvfrom(bufsiz)
if not data: break
print(data.decode('utf-8'))
c.close()
socketserver模块
提供了BaseServer
类, 和其子类TCPServer
, UDPServer
两个子类中提供了两个文件rfile
和wfile
, 对其读写相当于send
和recv
数据
服务端:
from socketserver import (TCPServer as TCP, StreamRequestHandler as SRH)
from time import ctime
host = ''
port = 1234
addr = (host, port)
class MyRequesthandler(SRH):
def handle(self):
self.data = self.rfile.readline().strip()
print('connected from:{0} \n receive: {1}'.format(
self.client_address,
self.data.decode('utf-8')
)
)
self.wfile.write(bytes('[{0}] {1}'.format(ctime(), self.data.decode('utf-8')), 'utf-8'))
tcpServ = TCP(addr, MyRequesthandler)
print('waiting...')
tcpServ.serve_forever()
客户端:
from socket import *
host = 'localhost'
port = 1234
bufsiz = 1024
addr = (host, port)
while True:
c = socket(AF_INET, SOCK_STREAM)
c.connect(addr)
data = input('> ')
if not data: break
c.send(bytes(data+'\r\n', 'utf-8'))
data = c.recv(bufsiz)
if not data: break
print(data.strip().decode('utf-8'))
c.close()
Twisted框架
Twisted框架是一个完整的事件驱动的网络框架, 功能比较强大
因特网客户端编程
Python提供了大量的因特网协议模块, 例如FTP, IMAP, POP, SMTP等等, 多而杂, 用到的时候再看