Python Network Programming

socket

socket.gethostbyname(hostname)

socket.gethostbyaddr(addr)

socket.getservbyname(name) 查询端口号(如name=’www’, 返回80)

socket.getserbyport(80) 返回’www’

127...* 是本地ip

10...* 172.16-31.. 192.168.. 为私有子网所预留。

子网掩码255.255.255.0 可以表述为***.***.***.***/24 (***=11111111,8位)

tcp

sock = socket.socket(xxx…) (参数参考https://www.cnblogs.com/wumingxiaoyao/p/7047658.html)( 一般要写SO_REUSERADDR以防同一端口最近关闭的连接还未关闭导致错误,因为关闭后会有CLOSE-WAIT和TIME-WAIT 状态)

sock.accept() 会创建一个连接套接字 (对应客户端发送的sock.connect())

sock.listen() 会创建一个监听套接字

sock.sendall() 实现了完整数据块传输,recvall需要自己写

sock.getsockname()

sock.bind(interface,port) interface取””空字符串表示接受任意网络接口的请求(0.0.0.0表示接受任意,py简化了)

sock.shutdown(xxx) 半开连接的操作

sock.makefile() 直接进行文件读写

tcp客户端服务端

#!/usr/bin/env python3

import argparse, socket

def recvall(sock, length):
    data = b''
    while len(data) < length:
        more = sock.recv(length - len(data))
        if not more:
            raise EOFError('was expecting %d bytes but only received'
                           ' %d bytes before the socket closed'
                           % (length, len(data)))
        data += more
    return data

def server(interface, port):
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    sock.bind((interface, port))
    sock.listen(1)
    print('Listening at', sock.getsockname())
    while True:
        print('Waiting to accept a new connection')
        sc, sockname = sock.accept()
        print('We have accepted a connection from', sockname)
        print('  Socket name:', sc.getsockname())
        print('  Socket peer:', sc.getpeername())
        message = recvall(sc, 16)
        print('  Incoming sixteen-octet message:', repr(message))
        sc.sendall(b'Farewell, client')
        sc.close()
        print('  Reply sent, socket closed')

def client(host, port):
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect((host, port))
    print('Client has been assigned socket name', sock.getsockname())
    sock.sendall(b'Hi there, server')
    reply = recvall(sock, 16)
    print('The server said', repr(reply))
    sock.close()

if __name__ == '__main__':
    choices = {'client': client, 'server': server}
    parser = argparse.ArgumentParser(description='Send and receive over TCP')
    parser.add_argument('role', choices=choices, help='which role to play')
    parser.add_argument('host', help='interface the server listens at;'
                        ' host the client sends to')
    parser.add_argument('-p', metavar='PORT', type=int, default=1060,
                        help='TCP port (default 1060)')
    args = parser.parse_args()
    function = choices[args.role]
    function(args.host, args.p)

DNS

socket.getaddrinfo

socket.getaddrinfo(host, port[, family[, socktype[, proto[, flags]]]]) 可解析得到IPv6地址。 返回创建一个套接字并发起连接所需的所有信息,返回的元组(family, socktype, proto, canonname, sockaddr)依次为:地址族、类型、协议代号、规范名、地址信息。用前三项作为socket构造参数,第五项为传入地址,可构造出一个连接connect()
flag:AI_V4MAPPED:返回IPv4映射到IPv6格式的IPv6地址.(http://www.ip2location.com/articles/ip2location-ipv4-mapped-ipv6-address)

  1. bind:为服务器绑定端口。 将host取None,返回合适的通配符地址,可用于bind。
  2. connect/sendto:连接。设置AI_ADDRCONFIG标记,讲所有无法连接的地址过滤掉。
    使用getaddrinfo
#!/usr/bin/env python3
# Foundations of Python Network Programming, Third Edition
# https://github.com/brandon-rhodes/fopnp/blob/m/py3/chapter04/www_ping.py
# Find the WWW service of an arbitrary host using getaddrinfo().

import argparse, socket, sys

def connect_to(hostname_or_ip):
    try:
        infolist = socket.getaddrinfo(
            hostname_or_ip, 'www', 0, socket.SOCK_STREAM, 0,
            socket.AI_ADDRCONFIG | socket.AI_V4MAPPED | socket.AI_CANONNAME,
            )
    except socket.gaierror as e:
        print('Name service failure:', e.args[1])
        sys.exit(1)

    info = infolist[0]  # per standard recommendation, try the first one
    socket_args = info[0:3]
    address = info[4]
    s = socket.socket(*socket_args)
    try:
        s.connect(address)
    except socket.error as e:
        print('Network failure:', e.args[1])
    else:
        print('Success: host', info[3], 'is listening on port 80')

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Try connecting to port 80')
    parser.add_argument('hostname', help='hostname that you want to contact')
    connect_to(parser.parse_args().hostname)

dns.resolver() 可进行DNS查询(https://github.com/brandon-rhodes/fopnp/blob/m/py3/chapter04/dns_mx.py)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值