socket模块网络编程

    1. socket()类
    # socket语法
    socket(socket_family, socket_type, protocol=0)
    # soket_family: AF_UNIT, AF_INET, AF_INET6...
    # socket_type: SOCK_STREAM(TCP), SOCK_DGRAM(UDP)
    # protocol默认为0
    
    # 创建TCP/IPv4套接字
    tcpSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 创建UDP/IPv6套接字
    tcpSock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
    
    1. 套接字对象(内置)方法
名 称 描 述
服务器套接字方法
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 套接字协议
    1. 创建 TCP 服务器
      $ vim tsTserv.py
  1 #!/usr/bin/python3
  2 # coding=utf-8
  3 
  4 # 导入socket模块,和时间模块的ctime()方法,返回当前时间戳
  5 import socket
  6 from time import ctime
  7 
  8 HOST = ''       # 空白地址,表示任何可用的地址
  9 PORT = 6666     # 随机端口
 10 BUFSIZ = 1024           # 缓冲区大小
 11 ADDR = (HOST, PORT)     # 地址
 12 
 13 # 创建一个tcp/ip套接字
 14 tcpSerSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 15 # 绑定的ip和端口并开启监听
 16 tcpSerSock.bind(ADDR)
 17 # 传入连接请求的最大数
 18 tcpSerSock.listen(5)
 19 
 20 # 等待用户客户端连接
 21 while True:
 22     # 输出提示信息
 23     print('[*] waiting for connection...')
 24     # 被动接受tcp连接,一直等待知道连接为止tcpCliSock为套接字,addr为元组(str, int)
 25     (tcpCliSock, addr) = tcpSerSock.accept()
 26     # 打印连接信息
 27     print('[+]...connected from: %s: %d' % (addr[0], addr[1]))
 28      
 29 
 30     # 接受用户输入并返回
 31     while True:
 32         # 接受BUFSIZ大小数据
 33         data = tcpCliSock.recv(BUFSIZ)
 34         # 当数据为空,则用户关闭连接,退出
 35         if not data:
 36             break
 37         # 返回时间戳+数据,python3使用byte
 38         tcpCliSock.send(b'[%s] %s' % (bytes(ctime(), 'utf-8'), data))
 39     # 关闭客户端连接
 40     tcpCliSock.close()
 41 # 关闭服务器
 42 tcpSerSock.close()
    1. 创建 TCP 客户端
      $ vim tsTclnt.py
  1 #!/usr/bin/python3
  2 # coding=utf-8
  3 
  4 import socket
  5 
  6 HOST = '127.0.0.1'
  7 PORT = 6666
  8 BUFSIZ = 1024
  9 ADDR = (HOST, PORT)
 10 
 11 tcpClntSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 12 # 连接目标主机
 13 tcpClntSock.connect(ADDR)
 14 
 15 while True:
 16     # 输入发送的数据
 17     data = input(">>> ")
 18 
 19     # 判断是否退出
 20     if data == 'exit':
 21         break
 22 
 23     # 发送信息,byte
 24     tcpClntSock.send(bytes(data, 'utf-8'))
 25     # 接受返回的数据
 26     result = tcpClntSock.recv(BUFSIZ)
 27     if not result:
 28         break
 29     # 打印数据,解码
 30     print(bytes.decode(result))
 31 # 关闭连接
 32 tcpClntSock.close()
    1. 执行 TCP 服务器和客户端
# 终端1
$ ./tsTserv.py                          #先开启服务端
[*] waiting for connection...           #等待用户连接
[+]...connected from: 127.0.0.1: 36712  #有客户端连接
[*] waiting for connection...           #连接断开,等待新的连接
# 终端2
$ ./tsTclnt.py                          #开启客户端
>>> hello                               #发送
[Mon Nov 27 08:36:45 2017] hello        #回包
>>> good bey                            #发送
[Mon Nov 27 08:37:36 2017] good bey     #回包
>>> exit                                #退出关闭连接
    1. 创建 UDP 服务器
  1 #!/usr/bin/python3
  2 # coding=utf-8
  3
  4 import socket
  5 from time import ctime
  6
  7 HOST = '127.0.0.1'
  8 PORT = 6666
  9 BUFSIZ = 1024
 10 ADDR = (HOST, PORT)
 11
 12 udpSerSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
 13 udpSerSock.bind(ADDR)
 14
 15 while True:
 16     print('[*] waiting for message...')
 17     # 接受数据
 18     (data, addr) = udpSerSock.recvfrom(BUFSIZ)
 19     # 返回数据
 20     udpSerSock.sendto(b'[%s] %s' % (bytes(ctime(), 'utf-8'), data), addr)
 21     # 打印信息
 22     print('[+]...received from and returned to: %s: %d' % (addr[0], addr[1]))
 23 udpSerSock.close()
    1. 创建 UDP 客户端
  1 #!/usr/bin/python3
  2 # coding=utf-8
  3
  4 import socket
  5
  6 HOST = '127.0.0.1'
  7 PORT = 6666
  8 BUFSIZ = 1024
  9 ADDR = (HOST, PORT)
 10
 11 udpClntSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
 12
 13 while True:
 14     data = input(">>> ")
 15
 16     if data == 'exit':
 17         break
 18
 19     # 发送信息,byte
 20     udpClntSock.sendto(bytes(data, 'utf-8'), ADDR)
 21     # 接受返回的数据
 22     (result, ADDR) = udpClntSock.recvfrom(BUFSIZ)
 23     if not result:
 24         break
 25     print(bytes.decode(result))
 26 udpClntSock.close()
    1. 执行 UDP 服务器和客户端
# 终端1
$ ./tsUserv.py                                         #开启udp服务器
[*] waiting for message...
[+]...received from and returned to: 127.0.0.1: 39160      #接受并返回
[*] waiting for message...
[+]...received from and returned to: 127.0.0.1: 39160
[*] waiting for message...

# 终端2
$ ./tsUclnt.py
>>> hello
[Mon Nov 27 10:25:27 2017] hello
>>> good bey!
[Mon Nov 27 10:25:34 2017] good bey!
>>> exit
    1. socket 模块属性
属 性 名 称 描 述
数据属性
AF_UNIX、AF_INET、AF_INET6 、AF_NETLINK 、AF_TIPC Python 中支持的套接字地址家族
SO_STREAM、SO_DGRAM 套接字类型(TCP=流,UDP=数据报)
has_ipv6 指示是否支持 IPv6 的布尔标记
异常
error 套接字相关错误
herror 主机和地址相关错误
gaierror 地址相关错误
timeout 超时时间
函数
socket() 以给定的地址家族、套接字类型和协议类型(可选)创建一个套接字对象
socketpair() 以给定的地址家族、套接字类型和协议类型(可选)创建一对套接字对象
create_connection() 常规函数,它接收一个地址(主机名,端口号)对,返回套接字对象
fromfd() 以一个打开的文件描述符创建一个套接字对象
ssl() 通过套接字启动一个安全套接字层连接;不执行证书验证
getaddrinfo() 获取一个五元组序列形式的地址信息
getnameinfo() 给定一个套接字地址,返回(主机名,端口号)二元组
getfqdn() 返回完整的域名
gethostname() 返回当前主机名
gethostbyname() 将一个主机名映射到它的 IP 地址
gethostbyname_ex() gethostbyname()的扩展版本,它返回主机名、别名主机集合和 IP 地址列表
gethostbyaddr() 将一个 IP 地址映射到 DNS 信息;返回与 gethostbyname_ex()相同的 3 元组
getprotobyname() 将一个协议名(如‘tcp’ )映射到一个数字
getservbyname()/getservbyport() 将一个服务名映射到一个端口号,或者反过来;对于任何一个函数来说协议名都是可选的
ntohl()/ntohs() 将来自网络的整数转换为主机字节顺序
htonl()/htons() 将来自主机的整数转换为网络字节顺序
inet_aton()/inet_ntoa() 将 IP 地址八进制字符串转换成 32 位的包格式,或者反过来(仅用于 IPv4 地址)
inet_pton()/inet_ntop() 将IP 地址字符串转换成打包的二进制格式,或者反过来(同时适用于 IPv4 和IPv6 地址)
getdefaulttimeout()/setdefaulttimeout() 以秒(浮点数)为单位返回默认套接字超时时间;以秒(浮点数)单位设置默认套接字超时时间

你可能感兴趣的:(socket模块网络编程)