Python - Socket 编程

  • 简述

    Python 提供了对网络服务的两个级别的访问。在底层,您可以访问底层操作系统中的基本套接字支持,这允许您为面向连接和无连接协议实现客户端和服务器。
    Python 也有提供对特定应用程序级网络协议(如 FTP、HTTP 等)的更高级别访问的库。
    套接字是双向通信通道的端点。套接字可以在进程内、同一台机器上的进程之间或不同大陆上的进程之间进行通信。我们使用python中的socket模块来创建和使用socket。
    套接字有自己的词汇 -
    序号 术语和说明
    1
    Domain
    用作传输机制的协议族。这些值是常量,例如 AF_INET、PF_INET、PF_UNIX、PF_X25 等。
    2
    type
    两个端点之间的通信类型,通常 SOCK_STREAM 用于面向连接的协议,SOCK_DGRAM 用于无连接协议。
    3
    protocol
    通常为零,这可用于识别域和类型内的协议变体。
    4
    hostname
    网络接口的标识符 -
    • 一个字符串,可以是主机名、点分四组地址或冒号(也可能是点)表示法的 IPV6 地址
    • 一个字符串“<broadcast>”,它指定一个 INADDR_BROADCAST 地址。
    • 一个零长度字符串,它指定 INADDR_ANY,或
    • 一个整数,解释为主机字节顺序的二进制地址。
    5
    port
    每台服务器都侦听调用一个或多个端口的客户端。端口可以是 Fixnum 端口号、包含端口号的字符串或服务名称。
  • Socket模块_

    要创建套接字,您必须使用Socket模块中可用的socket.socket()函数,该函数具有一般语法 -
    
    s = socket.socket (socket_family, socket_type, protocol=0)
    
    这是参数的描述 -
    • socket_family− 如前所述,这是 AF_UNIX 或 AF_INET。
    • socket_type− 这是 SOCK_STREAM 或 SOCK_DGRAM。
    • protocol− 这通常被忽略,默认为 0。
    一旦你有了socket对象,你就可以使用所需的函数来创建你的客户端或服务器程序。
  • 服务器套接字方法

    序号 方法和说明
    1
    s.bind()
    此方法将地址(主机名、端口号对)绑定到套接字。
    2
    s.listen()
    此方法设置并启动 TCP 侦听器。
    3
    s.accept()
    这被动地接受 TCP 客户端连接,等待连接到达(阻塞)。
  • 客户端套接字方法

    序号 方法和说明
    1
    s.connect()
    该方法主动发起 TCP 服务器连接。
  • 通用套接字方法

    序号 方法和说明
    1
    s.recv()
    此方法接收 TCP 消息
    2
    s.send()
    此方法传输 TCP 消息
    3
    s.recvfrom()
    该方法接收UDP消息
    4
    s.sendto()
    此方法传输 UDP 消息
    5
    s.close()
    此方法关闭套接字
    6
    socket.gethostname()
    返回主机名。
  • 一个简单的服务器

    要编写 Internet 服务器,我们使用socket套接字模块中可用的函数来创建套接字对象。然后使用套接字对象调用其他函数来设置套接字服务器。
    现在打电话bind(hostname, port)函数为给定主机上的服务指定端口
    接下来,调用返回对象的accept方法。此方法一直等到客户端连接到您指定的端口,然后返回一个连接对象,该对象表示与该客户端的连接。
    
    #!/usr/bin/python           # This is server.py file
    import socket               # Import socket module
    s = socket.socket()         # Create a socket object
    host = socket.gethostname() # Get local machine name
    port = 12345                # Reserve a port for your service.
    s.bind((host, port))        # Bind to the port
    s.listen(5)                 # Now wait for client connection.
    while True:
       c, addr = s.accept()     # Establish connection with client.
       print 'Got connection from', addr
       c.send('Thank you for connecting')
       c.close()                # Close the connection
    
  • 一个简单的客户端

    让我们编写一个非常简单的客户端程序,它打开到给定端口 12345 和给定主机的连接。使用 Python 的socket模块函数创建一个 socket 客户端非常简单。
    socket.connect(hosname, port )端口上打开与主机名的 TCP 连接。一旦你打开了一个套接字,你就可以像任何 IO 对象一样读取它。完成后,记得关闭它,就像关闭文件一样。
    以下代码是一个非常简单的客户端,它连接到给定的主机和端口,从套接字读取任何可用数据,然后退出 -
    
    #!/usr/bin/python           # This is client.py file
    import socket               # Import socket module
    s = socket.socket()         # Create a socket object
    host = socket.gethostname() # Get local machine name
    port = 12345                # Reserve a port for your service.
    s.connect((host, port))
    print s.recv(1024)
    s.close                     # Close the socket when done
    
    现在在后台运行这个 server.py,然后在 client.py 上面运行以查看结果。
    
    # Following would start a server in background.
    $ python server.py & 
    # Once server is started run client as follows:
    $ python client.py
    
    这将产生以下结果 -
    
    Got connection from ('127.0.0.1', 48437)
    Thank you for connecting
    
  • 带有公共 URL 的套接字

    在下面的示例中,我们使用 socket 模块中的一些方法来查找服务器的地址信息和主机名详细信息。
    
    import socket
    from pprint import pprint
    # get server address
    addrinfo = socket.getaddrinfo('cainiaoya.com', 'www')
    pprint(addrinfo)
    # get server hostname
    print socket.gethostname()
    
    当我们运行上述程序时,我们得到以下输出 -
    
    [(2, 1, 0, '', ('94.130.81.180', 80))]
    DESKTOP-JXYKQCPLP