• 最基础的Python的socket编程入门教程


    最基础的Python的socket编程入门教程

    本文介绍使用Python进行Socket网络编程,假设读者已经具备了基本的网络编程知识和Python的基本语法知识,本文中的代码如果没有说明则都是运行在Python 3.4下。

    Python的socket功能封装在socket库中,要使用socket,记得先import socket,socket库的详细介绍参见官方文档。
    创建Socket
    首先创建一个socket,使用socket库中得socket函数创建。    
    import socket    
    # create an INET, STREAM socket
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    例子中创建了一个TCP socket,socket.socket函数的前两个参数的默认值是socket.AF_INET和socket.SOCK_STREAM,创建TCP socket时可以直接写成socket.socket()。
    连接服务器

    使用socket的connect函数连接到服务器,以下几种参数都是合法的。    
    s.connect(('localhost', 8000))
    s.connect(('127.0.0.1', 8000))
    s.connect(('www.baidu.com', 80))

    发送数据

    发送数据有两个方法send和sendall,send不能保证所有的数据都发送完了,它会返回已发送数据的长度,程序要循环发送数据直到所有数据都已发送完毕。    
    def mysend(s, msg):
      total_len = len(msg)
      total_sent = 0
      while total_sent < total_len:
        sent = s.send(msg[total_sent:])
        if sent == 0:
          raise RuntimeError("socket connection broken")
        total_sent = sent

    sendall能够保证所有的数据都已发送完毕,除非发送过程中出现了错误,它实际上也是循环发送数据直到所有数据发送完成。

    这里还要讲一个需要特别注意的地方,从一个例子开始吧:
        
    import socket
    s = socket.socket()
    s.connect(('www.baidu.com', 80))
    s.sendall('test')

    都是上面讲过的东西,没什么特别的,分别在Python 2和Python 3中执行以上的代码,结果是:    
    # Python 2.7
    >>> import socket
    >>> s = socket.socket()
    >>> s.connect(('www.baidu.com', 80))
    >>> s.sendall('test')

    Python 2中执行成功。    
    # Python 3.4
    >>> import socket
    >>> s = socket.socket()
    >>> s.connect(('www.baidu.com', 80))
    >>> s.sendall('test')
    Traceback (most recent call last):
     File "", line 1, in
    TypeError: 'str' does not support the buffer interface

    Python 3中却发生了异常。

    同样的代码换个环境却不能执行了,我没有写错呀,怒砸电脑。好吧,你确实没写错,是环境变了,导致这个结果的变化请移步官方的说明。
    接收数据

    使用recv函数接收数据:
        
    data = s.recv(4096)

    在Python 3中返回的是bytes对象,在Python 2中返回的是string。注意函数返回的数据长度是小于或者等于参数指定的长度的,要接收到指定长度的数据,需要循环接收数据。
        
    def myreceive(s, msglen):
      chunks = []
      bytes_recd = 0
      while bytes_recd < msglen:
        chunk = s.recv(min(msglen - bytes_recd, 2048))
        if chunk == b'':
          raise RuntimeError("socket connection broken")
        chunks.append(chunk)
        bytes_recd = bytes_recd len(chunk)
      return b''.join(chunks)

    关闭连接

    当连接不再需要时可以使用close关闭socket连接,关闭后的连接不能再进行任何操作。当一个socket被回收时会自动关闭,但是不要依赖这种机制,不需要socket时就主动的close。
    服务端

    服务端程序执行的步骤:
    1. 创建服务端socket
    1. 将服务端socket绑定到指定的地址和端口
    1. 监听连接
    1. 接受客户端连接
    1. 处理客户端的数据
    1. 关闭客户端连接

    一个简单的echo server示例:    
    import socket
     
    HOST = ''
    PORT = 10022
     
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind((HOST, PORT))
    s.listen(10)
    conn, addr = s.accept()
    while True:
      data = conn.recv(1024)
      if not data:
        break
      conn.sendall(data)
    conn.close()

    客户端程序:    
    import socket
     
    HOST = 'localhost'
    PORT = 10022
     
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((HOST, PORT))
    s.sendall(b'hello socket')
    data = s.recv(1024)
    print('Received', repr(data))
    s.close()

    错误处理

    socket处理过程中发生错误会抛出异常,socket相关的异常有:

        - socket.error
        - socket.herror
        - socket.gaierror
        - socket.timeout
        
    import socket
     
    HOST = None
    PORT = 10022
     
    try:
      s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
      s.bind((HOST, PORT))
      s.listen(10)
    except: socket.error as msg:
      print(msg)

     

  • 相关阅读:
    读取文本文件中的中文打印到Eclipse控制台为何显示问号
    使用StringUtils需要引用的依賴
    Ajax跨域访问XML数据的另一种方式——使用YQL查询语句
    AngularJS快速入门指南15:API
    国外社交网站获取分享数量APIs
    AngularJS快速入门指南14:数据验证
    AngularJS快速入门指南13:表单
    AngularJS快速入门指南12:模块
    AngularJS快速入门指南11:事件
    AngularJS快速入门指南10:DOM节点
  • 原文地址:https://www.cnblogs.com/amengduo/p/9586260.html
Copyright © 2020-2023  润新知