• python3.x 基础八:socket网络编程


    Socket

    socket就是一直以来说的“套接字”,用于描述:ip:端口,是通信链的句柄,客户端通过这个句柄进行请求和响应

    • 普通文件的操作顺序:打开-读写-关闭,针对的是文件
    • socket是特殊的文件,操作顺序也是:打开-请求/相应-关闭,针对的是Client和Server之间的socket

    整过过程如下:

     

     socket方法

      |  bind(...)
         |      bind(address)
         |      
         |      Bind the socket to a local address.  For IP sockets, the address is a
         |      pair (host, port); the host must refer to the local host. For raw packet
         |      sockets the address is a tuple (ifname, proto [,pkttype [,hatype]])

    •  将套接字绑定大地址,如果是raw包,地址是元组形式(ip,port)

         |  close(...)
         |      close()
         |      
         |      Close the socket.  It cannot be used after this call.

    • 关闭套接字

         |  connect(...)
         |      connect(address)
         |      
         |      Connect the socket to a remote address.  For IP sockets, the address
         |      is a pair (host, port).

    • 链接到远程地址,如果是IP socket,地址是元组形式(ip,port)

         |  connect_ex(...)
         |      connect_ex(address) -> errno
         |      
         |      This is like connect(address), but returns an error code (the errno value)
         |      instead of raising an exception when an error occurs.

    • 同connect,当发生错误时返回错误代码,而不是异常

         |  detach(...)
         |      detach()
         |      
         |      Close the socket object without closing the underlying file descriptor.
         |      The object cannot be used after this call, but the file descriptor
         |      can be reused for other purposes.  The file descriptor is returned.

    • 关闭套接字对象,而不关闭文件描述符,文件描述符类似文件句柄

         |  fileno(...)
         |      fileno() -> integer
         |      
         |      Return the integer file descriptor of the socket.

    • 返回文件描述符

         |  getpeername(...)
         |      getpeername() -> address info
         |      Return the address of the remote endpoint.  For IP sockets, the address
         |      info is a pair (hostaddr, port).

    • 返回套接字的远程地址,一般是元组形式(ip,port)

         |  getsockname(...)
         |      getsockname() -> address info
         |      
         |      Return the address of the local endpoint.  For IP sockets, the address
         |      info is a pair (hostaddr, port).

    • 返回套接字自己的地址,一般是元组形式(ip,port)

         |  getsockopt(...)
         |      getsockopt(level, option[, buffersize]) -> value
         |      
         |      Get a socket option.  See the Unix manual for level and option.
         |      If a nonzero buffersize argument is given, the return value is a
         |      string of that length; otherwise it is an integer.

    • 获取套接字的选项

         |  gettimeout(...)
         |      gettimeout() -> timeout
         |      
         |      Returns the timeout in seconds (float) associated with socket
         |      operations. A timeout of None indicates that timeouts on socket
         |      operations are disabled.

    • 以秒返回套接字操作超时时间

         |  listen(...)
         |      listen([backlog])
         |      
         |      Enable a server to accept connections.  If backlog is specified, it must be
         |      at least 0 (if it is lower, it is set to 0); it specifies the number of
         |      unaccepted connections that the system will allow before refusing new
         |      connections. If not specified, a default reasonable value is chosen.

    • 使server端开始监听链接,backlog至少未0,指定了尚未被accept处理的连接个数,如果达到这个数目,后面的连接将被拒绝,如果不指定,系统会设置一个合理值

         |  recv(...)
         |      recv(buffersize[, flags]) -> data
         |      
         |      Receive up to buffersize bytes from the socket.  For the optional flags
         |      argument, see the Unix manual.  When no data is available, block until
         |      at least one byte is available or until the remote end is closed.  When
         |      the remote end is closed and all data is read, return the empty string.

    • 从套接字中能接收到的数据,buffersize指定最多可以接收的大小,以bytes形式返回

         |  recv_into(...)
         |      recv_into(buffer, [nbytes[, flags]]) -> nbytes_read
         |      
         |      A version of recv() that stores its data into a buffer rather than creating
         |      a new string.  Receive up to buffersize bytes from the socket.  If buffersize
         |      is not specified (or 0), receive up to the size available in the given buffer.
         |      
         |      See recv() for documentation about the flags.

    • 与recv类似,保存数据到缓存,而不是创建接收字符串

         |  recvfrom(...)
         |      recvfrom(buffersize[, flags]) -> (data, address info)
         |      
         |      Like recv(buffersize, flags) but also return the sender's address info.

    • 与recv类似,返回值是元组形式(data,address),data是包含接收数据的字符串,address是发送数据的套接字地址

         |  recvfrom_into(...)
         |      recvfrom_into(buffer[, nbytes[, flags]]) -> (nbytes, address info)
         |      
         |      Like recv_into(buffer[, nbytes[, flags]]) but also return the sender's address info.

    •  与recv_into类似,返回的是发送者的地址信息

         |  recvmsg(...)
         |      recvmsg(bufsize[, ancbufsize[, flags]]) -> (data, ancdata, msg_flags, address)


         |  recvmsg_into(...)
         |      recvmsg_into(buffers[, ancbufsize[, flags]]) -> (nbytes, ancdata, msg_flags, address)
        

         |  sendall(...)
         |      sendall(data[, flags])
         |      
         |      Send a data string to the socket.  For the optional flags
         |      argument, see the Unix manual.  This calls send() repeatedly
         |      until all data is sent.  If an error occurs, it's impossible
         |      to tell how much data has been sent.

    • 循环发送,直到发送完毕

         |  sendmsg(...)
         |      sendmsg(buffers[, ancdata[, flags[, address]]]) -> count
         |      
         |      Send normal and ancillary data to the socket, gathering the
         |      non-ancillary data from a series of buffers and concatenating it into
         |      a single message.  The buffers argument specifies the non-ancillary
         |      data as an iterable of bytes-like objects (e.g. bytes objects).
         |      The ancdata argument specifies the ancillary data (control messages)
         |      as an iterable of zero or more tuples (cmsg_level, cmsg_type,
         |      cmsg_data), where cmsg_level and cmsg_type are integers specifying the
         |      protocol level and protocol-specific type respectively, and cmsg_data
         |      is a bytes-like object holding the associated data.  The flags
         |      argument defaults to 0 and has the same meaning as for send().  If
         |      address is supplied and not None, it sets a destination address for
         |      the message.  The return value is the number of bytes of non-ancillary
         |      data sent.
         |  
         |  sendto(...)
         |      sendto(data[, flags], address) -> count
         |      
         |      Like send(data, flags) but allows specifying the destination address.
         |      For IP sockets, the address is a pair (hostaddr, port).

    • 类似send,将数据发送到套接字,指定远端目标地址,返回的是发送字节数,多用于UDP协议

         |  setblocking(...)
         |      setblocking(flag)
         |      
         |      Set the socket to blocking (flag is true) or non-blocking (false).
         |      setblocking(True) is equivalent to settimeout(None);
         |      setblocking(False) is equivalent to settimeout(0.0).

    •  是否阻塞,默认是True,等同settimeout(None),如果是False,accept和recv时无数据则报错,等同于settimeout(0.0)

         |  setsockopt(...)
         |      setsockopt(level, option, value)
         |      
         |      Set a socket option.  See the Unix manual for level and option.
         |      The value argument can either be an integer or a string.

    • 设置套接字选项,值参数可以是整形或者字符串

         |  settimeout(...)
         |      settimeout(timeout)
         |      
         |      Set a timeout on socket operations.  'timeout' can be a float,
         |      giving in seconds, or None.  Setting a timeout of None disables
         |      the timeout feature and is equivalent to setblocking(1).
         |      Setting a timeout of zero is the same as setblocking(0).

    • 设置套接字操作的超时时间,timeout是一个浮点数秒,None表示没有超时,指定超时时间等同setblocking(1),就是阻塞,如果没有超时间等同setblock(0)

         |  shutdown(...)
         |      shutdown(flag)
         |      
         |      Shut down the reading side of the socket (flag == SHUT_RD), the writing side
         |      of the socket (flag == SHUT_WR), or both ends (flag == SHUT_RDWR).

    • 关闭socket读的一端或者写的一端,或者同时关闭两端

    client:

    import socket
    client=socket.socket()  # 实例化一个socket类,同时生成socket链接对象
    client.connect(('localhost',8080)) # 链接目标,元组类型的主机+端口
    while True:
        msg=input('pls input something>>').strip()
        if not bool(msg):
            print('未输入任何内容')
            continue
        client.send(msg.encode("utf-8"))  # 指定编码格式utf-8 ,发送数据,python3只能发送byte类型
        data=client.recv(1024) # 接受窗口缓存大小,如果接收的内容大于窗口,则服务器的发送缓存会一直发送过来
        print(data.decode())  # 将byte类型转换成unicode
    client.close()

    1.发送字符串

    接收客户端请求,并返回结果的server:

    import socket
    server=socket.socket()
    server.bind(('localhost',8080))  # 服务端绑定监听主机+端口
    server.listen() #监听
    while True:
        print('begin to listening...')
        conn,addr=server.accept()
        #server.accept 等待链接进来,如果没有链接进来,则一直阻塞在这里
        #不能用data=server。accept()直接接收,多个链接进来会无法区分是哪个链接
        #使用标记方法,accept会返回两个值,一个是标记位,就是socket的句柄,一个是链接地址
        print('conn:%s 
     adr:%s'%(conn,addr))
        print('conntion is coming')
        while True:
            data=conn.recv(1024) # 设置socket句柄接收的窗口大小
            print('recv:',data.decode('utf-8'))
            if not data:
                print('client is lost')
                break
            conn.send(data.upper()) # 发送请求结果给客户端
    server.close()

    2.发送linux命令

    返回命令结果给客户端

    import os
    import socket
    server=socket.socket()
    server.bind(('localhost',8020))
    server.listen()
    while True:
        print('begin to listening...')
        conn, addr = server.accept()
        # print('conn:%s 
     adr:%s' % (conn, addr))
        print('conntion is coming')
        while True:
            data = conn.recv(1024)
            print('I had recv your request %s'%data)
            data=str(data,encoding="utf-8")
            print('data is %s'%data)
            print('change byte to str',data)
            if not data:
                print('client is lost')
                break
            res=os.popen(data).read()
            conn.send(bytes(res,encoding="utf-8"))
            print(len(data))
    server.close()

    3.传送文件

    client

    import socket
    client=socket.socket()  # 实例化一个socket类,同时生成socket链接对象
    client.connect(('localhost',8010)) # 链接目标,元组类型的主机+端口
    fd=open('../file.zip','wb')
    while True:
        msg=input('pls input something>>').strip()
        if not bool(msg):
            print('未输入任何内容')
            continue
        client.send(msg.encode("utf-8"))  # 指定编码格式utf-8 ,发送数据,python3只能发送byte类型
        # data=client.recv(1024) # 接受窗口缓存大小,如果接收的内容大于窗口,则服务器的发送缓存会一直发送过来
        file=client.recv(10240000)
        print('recv size is ',len(file))
        fd.write(file)
        fd.flush()
    client.close()

    server

    import socket
    server=socket.socket()
    server.bind(('localhost',8010))
    server.listen()
    while True:
        print('begin to listening...')
        conn, addr = server.accept()
        print('conn:%s 
     adr:%s' % (conn, addr))
        print('conntion is coming')
        while True:
            data = conn.recv(1024)
            print('I had recv your request %s'%data)
            data=str(data,encoding="utf-8")
            print('change byte to str',data)
            if not data:
                print('client is lost')
                break
            with open('../MDMCSL71008_40-20004526.ZIP','rb') as fdr:
                file=fdr.read()
            print('file size is ',len(file))
            conn.sendall(file)
            print('file had ben sent')
            break
    
    server.close()

    注意:接收和发送的缓存有上限,大文件不能一次发送过来或者一次接收

  • 相关阅读:
    Visual Assist X 安装失败解决办法
    ACM-水池数目问题
    代码生成器 CodeBuilder 2.7 新版发布
    Fireasy 官网改版
    跟我学: 使用 fireasy 搭建 asp.net core 项目系列之三 —— 配置
    跟我学: 使用 fireasy 搭建 asp.net core 项目系列之二 —— 准备
    跟我学: 使用 fireasy 搭建 asp.net core 项目系列之一 —— 开篇
    nopCommerce 学习之路(一)Nop之强制拆迁
    平庸技术流,用 WebApi +AngularJS 实现网络爬虫
    nopCommerce 学习之路(二)从EF到NPoco
  • 原文地址:https://www.cnblogs.com/jenvid/p/8204626.html
Copyright © 2020-2023  润新知