zoukankan      html  css  js  c++  java
  • 高级网络操作

    Python对TCP/IP网络的支持,为不同类型的程序提供了很多有用的特性

    1>半开放socket(Half-open sockets),它可以使你关闭一个方向上的通信

    2>超时(Timeouts),它在等待了一定时间后,如果没有可以连接的网路则产生异常

    3>传送字符串和标记字符串结束的技巧

    4>网络字节命令,一般用于C-based协议的通信

    5>广播(Broadcasts),它会同时向多个机器发送数据

    6>使用IPV6,下一代互联网协议

    7>绑定到特殊的地址或接口

    8>使用poll和select同时查找多个不同的事件

    超时:

    eg:

    #Echo Server with Timeouts --------- timeoutserver.py
    
    import socket,traceback
    
    host = ''
    port = 51423
    
    s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
    s.bind((host,port))
    s.listen(1)
    
    
    while True:
        try:
            clientsock,clientaddr = s.accept()
        except KeyboardInterrupt:
            raise
        except:
            traceback.print_exec()
            continue
        clientsock.settimeout(5)
    
        try:
            print "Got connection from",clientsock.getpeername()
            while True:
                data = clientsock.recv(4096)
                if not len(data): 
                    break
                clientsock.sendall(data)
        except (KeyboardInterrupt,SystemExit):
            raise
        except socket.timeout:
            pass
        except:
            traceback.print_exc()
    
        try:
            clientsock.close()
        except KeyboardInterrupt:
            raise
        except:
            traceback.print_exc()

    网络字节:

    eg:

    #Network Byte Order ----  nbo.py
    
    import struct,sys
    
    def htons(num):
        return struct.pack('!H',num)
    
    def htonl(num):
        return struct.pack('!I',num);
    
    def ntohs(data):
        return struct.unpack('!H',data)[0]
    
    def ntohl(data):
        return struct.unpack('!I',data)[0]
    
    def sendstring(data):
        return htonl(len(data))+data
    
    print "Enter a string:"
    str = sys.stdin.readline().rstrip()
    print repr(sendstring(str))

    广播:

    服务器:

    #UDP Broadcase Server  ---   bcastreceiver.py
    
    import socket,traceback
    
    host = ''
    port = 51423
    
    s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
    s.setsockopt(socket.SOL_SOCKET,socket.SO_BROADCAST,1)
    s.bind((host,port))
    
    while True:
        try:
            message,address =s.recvfrom(8192)
            print "Got data from ",address
            s.sendto("I am here",address)
        except (KeyboardInterrupt,SystemExit):
            raise
        except:
            traceback.print_exc()

    客户端:

    #Broadcast Sender ---- bcastsender.py
    
    import socket,sys
    dest = ('<broadcast>',51423)
    
    s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    s.setsockopt(socket.SOL_SOCKET,socket.SO_BROADCAST,1)
    s.sendto("Hello",dest)
    
    print "Looking for replies; press Ctrl-C to stop."
    
    while True:
        (buf,address) = s.recvfrom(2048)
        if not len(buf):
            break
        print "Received from %s: %s" % (address,buf)

    IPV6:

    #getaddrinfo() display
    #Give a host and a port on the command line
    
    import socket,sys
    
    host,port = sys.argv[1:]
    
    results = socket.getaddrinfo(host,port,0,socket.SOCK_STREAM)
    
    for result in results:
        print "-"*60
    
        if result[0] == socket.AF_INET:
            print "Family: AF_INET"
        elif result[0] == socket.AF_INET6:
            print "Family: AF_INET6"
        else:
            print "Family:",result[0]
    
        if result[1] == socket.SOCK_STREAM:
            print "Socket Type: SOCK_STREAM"
        elif result[1] == socket.SOCK_DGRAM:
            print "Socket Type: SOCK_DGRAM"
    
        print "Protocol:",result[2]
        print "Canonical Name:",result[3]
        print "Socket Address:",result[4]

    Family参数:

    #Connect Example with ipv6 Awareness  -------------   ipv6connect.py
    
    import socket,sys
    
    def getaddrinfo_pref(host,port,socktype,familypreference=socket.AF_INET):
        """Given a host,port,and socktype (usually socket.SOCK_STREAM or socket.SOCK_DGRAM)),
        looks up information with both IPV4 and IPV6.
        If information is found corresponding to familypreference,it is returned.
        Otherwise,any information found is returned.The family preference defaults
        to IPV4(socket.AF_INET) but you could alse set it to socket.AF_INET6 for IPV6
    
        The return value is the appropriate tuple returned from
        socket.getaddrinfo()."""
    
        results = socket.getaddrinfo(host,port,0,socktype)
    
        for result in results:
            if result[0] == familypreference:
                return result
        return results[0]
    
    host = sys.argv[1]
    port = 'http'
    
    c = getaddrinfo_pref(host,port,socket.SOCK_STREAM)
    print "Connecting to",c[4]
    
    s = socket.socket(c[0],c[1])
    s.connect(c[4])
    s.sendall("HEAD / HTTP/1.0
    
    ")
    
    while True:
        buf = s.recv(4096)
    
        if not len(buf):
            break
        sys.stdout.write(buf)

    绑定地址:

    #Echo Server Bound to Specific Address
    #bindserver.py
    
    import socket,traceback
    
    host = '127.0.0.1'
    port = 51423
    
    
    s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
    s.bind((host,port))
    s.listen(1)
    
    
    while True:
        clientsock,clientaddr = s.accept()
    
        print "Got connection from",clientsock.getpeername()
    
        while True:
            data = clientsock.recv(4096)
            if not len(data):
                break
            clientsock.sendall(data)
    
        clientsock.close()

    poll:

    #Nonblocking I/O
    #pollclient.py
    
    import socket,sys,select
    
    
    port = 51423
    host = 'localhost'
    
    spinsize = 10
    spinpos = 0
    spindir = 1
    
    def spin():
        global spinsize,spinpos,spindir
    
        spinstr = '.' * spinpos + '|' + '.'*(spinsize-spinpos-1)
        sys.stdout.write('
    '+spinstr+' ')
        sys.stdout.flush()
    
        spinpos += spindir
    
        if spinpos < 0:
            spindir = 1
            spinpos = 1
        elif spinpos >= spinsize:
            spinpos -= 2
            spindir = -1
    
    s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    s.connect((host,port))
    
    p = select.poll()
    
    p.register(s.fileno(),select.POLLIN | select.POLLERR | select.POLLHUP)
    
    while True:
        results = p.poll(50)
    
        if len(results):
            if results[0][1] == select.POLLIN:
                data = s.recv(4096)
                if not len(data):
                    print ("
    Remove end closed connection ; exiting.")
                    break
                sys.stdout.write("
    Received: " + data)
                sys.stdout.flush()
    
            else:
                print "
    Problem occurred exitng."
                sys.exit(0)
        spin()

    select:

    #selectclient.py
    
    import socket,sys,select
    
    port = 51423
    host = 'localhost'
    
    spinsize = 10
    spinpos = 0
    spindir = 1
    
    def spin():
        global spinsize,spinpos,spindir
    
        spinstr = '.' * spinpos + '|' + '.' *(spinsize - spinpos -1)
        sys.stdout.write('
    ' + spinstr +' ')
        sys.stdout.flush()
    
        spinpos += spindir
    
        if spinpos < 0:
            spindir = 1
            spinpos = 1
        elif spinpos >= spinsize:
            spinpos -= 2
            spindir = -1
    
    s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    s.connect((host,port))
    
    while True:
        infds,outfds,errfds = select.select([s],[],[s],0.05)
    
        if len(infds):
        #Normally,one would use something like "for fd in infds" here
        #We don't bother since there will only ever be a single file
        #descriptor there.
    
            data = s.recv(4096)
            if not len(data):
                print("
    Remote end closed connection; Exiting.")
                break
            sys.stdout.write("
    Received: " + data)
            sys.stdout.flush()
    
        if len(errfds):
            print "
    Problen occurred; exiting."
            sys.exit(0)
        spin()
  • 相关阅读:
    webpackHotMiddleware改造成koa支持的中间件
    webpack-dev-middleware改造成koa中件间
    Vue3学习笔记
    当前工程中typescritpt依赖包与依赖包中依赖包类型不一致如何解决
    typescript中使用Object.keys
    获取东8区时间
    SyntaxError: Invalid regular expression: invalid group specifier name
    测试代码框
    ST Lab2 Selenium
    ST HW3
  • 原文地址:https://www.cnblogs.com/lfsblack/p/3301460.html
Copyright © 2011-2022 走看看