zoukankan      html  css  js  c++  java
  • Python 网络编程

    第1章        客户/服务器网络介绍

    1.       一个gopher的客户端。

    2.       socketmakefile

    3.       一个简单的服务器,socket.setsockopt() socket.bind(host,port), socket.listen(1), socket.accept()

     

    第2章        网络客户端

    1.    使用socket对象

    # -*- coding: cp936 -*-

    import socket

    #创建socket对象

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    #连接

    s.connect(('www.cainiao8.com',80))

    #获取信息

    print 'getsockname(): ' , s.getsockname()

    print 'getpeername():' , s.getpeername()

     

    其中socket.AF_INETIPV4的协议族。TCP对应SOCK_STREAM, UDP对应SOCK_DGRAM

     

    2.    根据服务名称获取端口号码

     

    >>> socket.getservbyname('http')

    80

     

    3.    socket的异常处理

    socket可能抛出4种异常:errotgaierrorherrortimeout。在写操作之后最好使用shutdown()来确保真的没有异常发生。第2章的shutdown.py例程介绍了异常的捕获。shutdownfile.py介绍了使用makefile()之后使用文件方式使用socket时候对异常的捕获,异常仍然是socket.error,作者建议尽量不要在使用文件方式的时候用缓冲器。

    4.    UDP

    使用UDP的主要区别:

    l  socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

    l  可以不用connect,直接 s.sendto(‘’, (host, port))

    详见第2章的udp.pyudptime.py

     

     

     

    3 网络服务器

    1. 建立服务器的步骤:

    1)       建立socket对象

    2)       设置socket选项

    cockopts.py文件可以列出当前系统下Python支持的socket选项。

    import socket

    solist = [x for x in dir(socket) if x.startswith('SO_')]

    solist.sort()

    for x in solist:

        print x

    在调试程序的时候,最常用的是将SO_REUSEADDR设置为True,代表在程序进程结束后立即释放进程占用的端口。

    3)       绑定端口

    例如绑定80端口,bind的第一个参数是IP地址:

    s.bind(‘’,80)

    4)       侦听连接

    s.listen(5)

    表示允许的队列中等待的连接数。

     

    2. 接受连接

    basicserver.py是一个简单的服务器,在收到连接的时候简单的print一条信息,并且将连接关闭。主要源代码如下:

    host = ''                               # Bind to all interfaces

    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 1:

        clientsock, clientaddr = s.accept()

        print "Got connection from", clientsock.getpeername()

        clientsock.close()

    Windows下使用IDLE运行会造成IDLE假死,直接双击运行没问题。如下图:

     

     

    服务器

     

     

     

     

    3.    异常处理

    考虑到服务器的容错能力,errorserver.py使用了各种try将程序包围起来。

    4.    UDP

    不需要listen。大致代码如下:

    while 1:

        try:

            message, address = s.recvfrom(8192)

            s.sendto(message, address)

    5.    inetdxinetd

    像写普通Python程序一样写服务器。

    6.    syslog

    记录信息,Windows没有syslog

    7.    避免死锁

    使用一个客户端和服务器端的例子来说明一种死锁的可能情况。客户端试图向服务器发送一个大数据,而服务器每次读取一部分数据后给客户端发送一个回应,但是由于客户端的设计是在发送完之后才进行读取,因此服务器发送的回应被缓存。如此一来,缓存逐渐达到系统极限。服务器端由于缓存不足而无法再发送,卡在sendall一处,客户端试图发送数据,但是服务器端卡了,无法进行recv,所以客户端也卡在这里,形成死锁。

     

    4 域名系统

    1.        执行基本的DNS查询

    使用socket模块的getaddrinfo()函数,它返回一个元组的列表。

    >>> import socket

    >>> res = socket.getaddrinfo('google.com',None)

    >>> print res

    [(2, 0, 0, '', ('74.125.127.100', 0)), (2, 0, 0, '', ('74.125.67.100', 0)), (2, 0, 0, '', ('74.125.45.100', 0))]

    2.        反向查找

    使用socket模块的gethostbyaddr

    >>> import socket

    >>> res = socket.getaddrinfo('google.com',None)

    >>> res

    [(2, 0, 0, '', ('74.125.67.100', 0)), (2, 0, 0, '', ('74.125.45.100', 0)), (2, 0, 0, '', ('74.125.127.100', 0))]

    >>> res = socket.gethostbyaddr('74.125.67.100')

    >>> res

    ('gw-in-f100.google.com', [], ['74.125.67.100'])

     

    反向查找的结果可能是对方IP刻意伪造的,gethostbyaddr-paranoid.py在反向查找之后再进行正向的查找,可以确保信息的正确性。

     

    书后面介绍了利用PyDNS进行高级的DNS查找功能,搞了老半天,不过没安装成功。

    5 高级网络操作

    1. 半开放socket

    只可以发送或者接收的socketshutdown(0)表示禁止将来读,shutdown(1)表示禁止将来写,2表示禁止读和写。01的效果可以累加。

    2. 超时

    timeoutserver.py演示了超时的用法,调用settimeout方法,主要代码如下:

    #建立socket,绑定到端口

    while 1:

        try:

            clientsock, clientaddr = s.accept()

    ……

        clientsock.settimeout(5)

    如果客户端在限定时间之内没有发送内容,连接就会被服务器断开。

    3. 广播

    接收端需要设置socket广播选项:

    s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)

    发送方除了设置那以上选项外,sendTo的参数不再使用IP地址,而是使用'<broadcast>'

    4. poll

    避免在socket上的I/O将程序阻塞。pollclient.py介绍了poll的使用方法:

    ……

    #ppoll对象。

    p = select.poll()

    #注册到感兴趣的socket上。

    p.register(s.fileno(), select.POLLIN | select.POLLERR | select.POLLHUP)

    while 1:

             #50毫秒返回一次,如果没有结果就返回空列表。

        results = p.poll()

        if len(results):

            if results[0][1] == select.POLLIN:

                data = s.recv(4096)

                if not len(data):

                    print("/rRemote end closed connection; exiting.")

                    break

                # Only one item in here -- if there's anything, it's for us.

                sys.stdout.write("/rReceived: " + data)

                sys.stdout.flush()

            else:

                print "/rProblem occured; exiting."

                sys.exit(0)

    #50毫秒要执行的操作。

    spin()

     

  • 相关阅读:
    转:js中javascript:void(0) 真正含义
    Chrome Capabilities & ChromeOptions
    scrapy
    远离DoS攻击 Windows Server 2016发布DNS政策
    windows server 2012 AD 活动目录部署系列(五)备份和还原域控制器
    windows server 2012 AD 活动目录部署系列(七)Active Directory 的授权还原
    对AD域进行定期自动备份设置图解
    教程:使用Diskpart创建、扩展或删除磁盘分区
    虚拟化天花板将近,后虚拟化时代如何应对?
    图样图森破 设置虚拟机优先级真的很容易?
  • 原文地址:https://www.cnblogs.com/lhj588/p/2521696.html
Copyright © 2011-2022 走看看