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

    Date: 2019-06-10

    Author: Sun

    1. Python TCP通信实现

    socket()函数

    Python 中,我们用 socket()函数来创建套接字,语法格式如下:

    socket.socket([family[, type[, proto]]])
    

    参数

    • family: 套接字家族可以使AF_UNIX或者AF_INET

    • type: 套接字类型可以根据是面向连接的还是非连接分为SOCK_STREAMSOCK_DGRAM

    • protocol: 一般不填默认为0.

    注:

    ​ socket只能发送字节类型的数据 所以在发送时要将发送的数据通过str.encode() 转为字节类型,接收时在通过str.decode()转为字符串。

    Socket 对象(内建)方法

    函数 描述
    服务器端套接字
    s.bind() 绑定地址(host,port)到套接字, 在AF_INET下,以元组(host,port)的形式表示地址。
    s.listen() 开始TCP监听。backlog指定在拒绝连接之前,操作系统可以挂起的最大连接数量。该值至少为1,大部分应用程序设为5就可以了。
    s.accept() 被动接受TCP客户端连接,(阻塞式)等待连接的到来
    客户端套接字
    s.connect() 主动初始化TCP服务器连接,。一般address的格式为元组(hostname,port),如果连接出错,返回socket.error错误。
    s.connect_ex() connect()函数的扩展版本,出错时返回出错码,而不是抛出异常
    公共用途的套接字函数
    s.recv() 接收TCP数据,数据以字符串形式返回,bufsize指定要接收的最大数据量。flag提供有关消息的其他信息,通常可以忽略。
    s.send() 发送TCP数据,将string中的数据发送到连接的套接字。返回值是要发送的字节数量,该数量可能小于string的字节大小。
    s.sendall() 完整发送TCP数据,完整发送TCP数据。将string中的数据发送到连接的套接字,但在返回之前会尝试发送所有数据。成功返回None,失败则抛出异常。
    s.recvfrom() 接收UDP数据,与recv()类似,但返回值是(data,address)。其中data是包含接收数据的字符串,address是发送数据的套接字地址。
    s.sendto() 发送UDP数据,将数据发送到套接字,address是形式为(ipaddr,port)的元组,指定远程地址。返回值是发送的字节数。
    s.close() 关闭套接字
    s.getpeername() 返回连接套接字的远程地址。返回值通常是元组(ipaddr,port)。
    s.getsockname() 返回套接字自己的地址。通常是一个元组(ipaddr,port)
    s.setsockopt(level,optname,value) 设置给定套接字选项的值。
    s.getsockopt(level,optname[.buflen]) 返回套接字选项的值。
    s.settimeout(timeout) 设置套接字操作的超时期,timeout是一个浮点数,单位是秒。值为None表示没有超时期。一般,超时期应该在刚创建套接字时设置,因为它们可能用于连接的操作(如connect())
    s.gettimeout() 返回当前超时期的值,单位是秒,如果没有设置超时期,则返回None。
    s.fileno() 返回套接字的文件描述符。
    s.setblocking(flag) 如果flag为0,则将套接字设为非阻塞模式,否则将套接字设为阻塞模式(默认值)。非阻塞模式下,如果调用recv()没有发现任何数据,或send()调用无法立即发送数据,那么将引起socket.error异常。
    s.makefile() 创建一个与该套接字相关连的文件

    socket异常

    Exception 解释
    socket.error 由Socket相关错误引发
    socket.herror 由地址相关错误引发
    socket.gaierror 由地址相关错误,如getaddrinfo()或getnameinfo()引发
    socket.timeout 当socket出现超时时引发。超时时间由settimeout()提前设定

    交互过程

    TCP服务端:

    1 创建套接字,绑定套接字到本地IP与端口

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

    2 开始监听连接

    s.listen()

    3 进入循环,不断接受客户端的连接请求

    s.accept()

    4 然后接收传来的数据,并发送给对方数据

    s.recv() , s.send()

    5 传输完毕后,关闭套接字

    s.close()

    TCP客户端:

    1 创建套接字,连接远端地址

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

    2 连接后发送数据和接收数据

    s.send(), s.recv()

    3 传输完毕后,关闭套接字

    s.close()

    2. TCP协议的Python实现

    服务器端:

    # -*- coding: utf-8 -*-
    __author__ = 'sun'
    __date__ = '2019/6/10 0:13'
    
    from socket import *
    from time import ctime
    HOST = ''
    PORT = 21567
    BUFSIZ = 1024
    ADDR = (HOST, PORT)
    tcpSerSock = socket(AF_INET, SOCK_STREAM) ##创建服务器TCP套接字
    tcpSerSock.bind(ADDR)
    tcpSerSock.listen(5)
    while True:
      print('waiting for connection...')
      tcpCliSock, addr = tcpSerSock.accept() ##等待客户端连接
      print('...connected from:', addr)
      while True:
        data = tcpCliSock.recv(BUFSIZ) ##监听客户端是否发送消息
        print(data)
        if not data:
          break
        tcpCliSock.send(data)
      tcpCliSock.close()	
    
    tcpSerSock.close()
    

    客户端代码:

    # -*- coding: utf-8 -*-
    __author__ = 'sun'
    __date__ = '2019/6/10 9:30'
    
    from socket import *
    
    HOST = 'localhost'
    PORT = 21567
    BUFSIZ = 1024
    ADDR = (HOST, PORT)
    tcpCliSock = socket(AF_INET, SOCK_STREAM)  ##创建客户端TCP套接字
    tcpCliSock.connect(ADDR) ##连接服务器
    while True:
      data = input('> ')
      if not data:
        break
      tcpCliSock.send(data.encode(encoding='utf8'))
      data = tcpCliSock.recv(BUFSIZ) ##监听客户端发送消息
      if not data:
        break
      print(data)
    tcpCliSock.close()
    

    3. Python UDP通信实现

    UDP则是面向无连接的协议。

    使用UDP协议时,不需要建立连接,只需要知道对方的IP地址和端口号,就可以直接发数据包。但是,能不能到达就不知道了。

    虽然用UDP传输数据不可靠,但它的优点是和TCP比,速度快,对于不要求可靠到达的数据,就可以使用UDP协议。

    服务器端代码:

    import socket
    
    '''
    使用UDP协议时,不需要建立连接,只需要知道对方的IP地址和端口号,就可以直接发数据包。但是,能不能到达就不知道了。
    
    虽然用UDP传输数据不可靠,但它的优点是和TCP比,速度快,对于不要求可靠到达的数据,就可以使用UDP协议。
    
    我们来看看如何通过UDP协议传输数据。和TCP类似,使用UDP的通信双方也分为客户端和服务器。服务器首先需要绑定端口
    绑定端口和TCP一样,但是不需要调用listen()方法,而是直接接收来自任何客户端的数据
    '''
    # ipv4        SOCK_DGRAM指定了这个Socket的类型是UDP
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    # 绑定 客户端口和地址:
    s.bind(('127.0.0.1', 9999))
    print('Bind UDP on 9999...')
    while True:
        # 接收数据 自动阻塞 等待客户端请求:
        data, addr = s.recvfrom(1024)
        print('Received from %s:%s.' % addr)
        s.sendto('Hello, %s!' % data, addr)
    # recvfrom()方法返回数据和客户端的地址与端口,这样,服务器收到数据后,直接调用sendto()就可以把数据用UDP发给客户端。
    

    客户端代码

    import socket
    
    '''
    客户端使用UDP时,首先仍然创建基于UDP的Socket,然后,不需要调用connect(),直接通过sendto()给服务器发数据:
    '''
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    
    for data in ['python', 'java', 'c']:
        # 发送数据:
        s.sendto(data, ('127.0.0.1', 9999))
        # 接收数据:
        print(s.recv(1024))
    s.close()
    
  • 相关阅读:
    反射+自定义注解,实现获取注解标记的属性
    jeecg导出Excel
    Date类的getYear(),getMonth过时,现在的获取方法
    Mysql的sql语句,Delete 中包含 not in
    EhCache与Redis的比较
    SpringMVC+Bootstrap项目
    按位运算| ^
    按步长检索数据,放缓有问题数据的处理
    DateTime 格式相比较,timestampdiff() 函数的运用
    作用域在函数定义时就已经确定了。而不是在函数调用时确定
  • 原文地址:https://www.cnblogs.com/sunBinary/p/11000634.html
Copyright © 2011-2022 走看看