• 网络模块socket


    网络模块socket

    实现本地收发

    • 简单的尴聊,实现服务器和客户端的文字传输

      TCP协议情况

        #server.py
        import socket	#导入socket模块
        from socket import SOL_SOCKET, SO_REUSEADDR	#记住这个模块
        
        sk = socket.socket()	#实例化socket对象
        sk.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)	#这行代码是为了实现端口继续利用的
        sk.bind(('127.0.0.1', 8080))	#为sk对象绑定一个ip和一个端口
        sk.listen()	#启动监听
        conn, addr = sk.accept()	#等待一个客户端的连接
        while 1:
            ret = conn.recv(1024).decode('utf-8')	#等待客户端发送消息
        
            if ret == 'bye':
                break
            print(ret)
            info = input('反馈: ')
            conn.send(bytes(info, encoding='utf-8'))	#向客户端发动消息
        
        conn.close()
        sk.close()
        ___________________________________________________
        ___________________________________________________
        #client
        import socket
      
        sk = socket.socket()
        sk.connect(('127.0.0.1', 8080))
        while 1:
            info = input('输入: ')
            sk.send(bytes(info, encoding='utf-8'))
            if info == 'bye':
                break
        
            ret = sk.recv(1024).decode('utf-8')
            print(ret)
        
        sk.close()
      

      改进版,为聊天消息加入时间

        #server
        import socket
        from socket import SOL_SOCKET, SO_REUSEADDR
        from time import ctime, time
        
        sk = socket.socket()
        sk.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
        sk.bind(('127.0.0.1', 8080))
        sk.listen()
        conn, addr = sk.accept()
        while 1:
            t = ctime(float(conn.recv(1024).decode('utf-8')))
            ret = conn.recv(1024).decode('utf-8')
        
            if ret == 'bye':
                break
            print('{}收到{}'.format(t, ret))
            info = input('反馈: ')
            conn.send(bytes(info, encoding='utf-8'))
            conn.send(bytes(str(time()), encoding='utf-8'))
        
        conn.close()
        sk.close()
        ----------------------------------------------
        ----------------------------------------------
        #client
        import socket
        from time import time, ctime
        
        sk = socket.socket()
        
        sk.connect(('127.0.0.1', 8080))
        while 1:
            info = input('输入: ')
            sk.send(bytes(str(time()), encoding='utf-8'))
            sk.send(bytes(info, encoding='utf-8'))
            if info == 'bye':
                break
        
            ret = sk.recv(1024).decode('utf-8')
            t = ctime(float(sk.recv(1024).decode('utf-8')))
            print(t, ret)
        
        sk.close()
      
      • TCP协议下只能允许一个客户端链接,多个客户端连接需要排队,等待第一个连接断开才能接入连接

      __UDP协议__情况

        #server
        #创建一个UDP协议的服务器
        import socket
        
        sk = socket.socket(type=socket.SOCK_DGRAM)    #实例化一个socket对象
        sk.bind(('127.0.0.1', 8081))    #给服务器绑定一个ip和端口
        
        conn, addr = sk.recvfrom(1024)  #接受消息,接收到消息内容和对方机器地址
        print(conn.decode('utf-8'), addr)
        
        sk.sendto(b'bye', addr)
        
        sk.close()
        --------------------------------
        --------------------------------
        #client
        #创建一个UDP客户端
        import socket
        
        sk = socket.socket(type=socket.SOCK_DGRAM)    #创建socket对象
        
        ip_port = ('127.0.0.1', 8081)
        sk.sendto(b'hello', ip_port)
        
        conn, addr = sk.recvfrom(1024)
        print(conn.decode('utf-8'), addr)
        
        sk.close()
      

    黏包现象

    • 出现在TCP协议中,如果一个包在一次发送中没有完全接收将会在下一次接收时继续接收

    • 可以理解成管道拥堵,再次接收会获取管道中的信息

    • 在UDP协议中没有黏包现象,没有接收完毕的包将直接丢弃

    • 黏包涉及到TCP协议自带的拆包机制,一种优化文件传输的机制

      黏包出现的两种情况

      1. 数据包太长,服务器接收参数小于数据包的长度
      2. 两个数据包的发送时间太近,神奇的某算法将其整合成一个数据包发送

      解决黏包的方案

      • 每次发送信息之前,先向服务器反馈信息的长度,告知服务器即将接收数据的长度

          #server
          import socket
          from socket import SOL_SOCKET, SO_REUSEADDR
          
          sk = socket.socket()
          sk.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
          sk.bind(('127.0.0.1', 8080))
          sk.listen()
          conn, addr = sk.accept()
          #服务器发送命令
          cmd = input('输入需要发送的命令: ')
          conn.send(bytes(cmd, encoding='utf-8'))
          print('命令已经发送!')
          
          #接收命令反馈信息的长度
          num = int(conn.recv(10).decode('utf-8'))
          print('接收到长度,长度是{}'.format(num))
          
          #反馈给客户端已经收到长度信息
          conn.send(b'Roger that')
          
          #接收命令反馈信息
          msg = conn.recv(num).decode('utf-8')
          print('接收到信息')
          #打印命令返回信息
          print(msg)
          #反馈信息给客户端
          conn.send(bytes('服务器说:接收完毕', encoding='utf-8'))
          #关闭服务
          conn.close()
          sk.close()
        
          -----------------------------
          -----------------------------
          #client
          import socket
          import subprocess
          import time
          
          sk = socket.socket()
          sk.connect(('127.0.0.1', 8080))
          #接收服务器命令
          cmd = sk.recv(1024).decode('utf-8')
          print(cmd)
          #将命令传给控制台
          ret = subprocess.Popen(cmd, shell=True,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE)
          print('控制台已经接收到命令')
          #将控制台传回的信息长度反馈给服务器
          std_out = ret.stdout.read()
          std_err = ret.stderr.read()
          num = len(std_out) + len(std_err)
          sk.send(bytes(str(num), encoding='utf-8'))
          print('控制台输出信息的长度已经反馈')
          
          #询问服务器收到长度了不
          has_len = sk.recv(1024)
          print(has_len.decode('utf-8'))
          
          
          #将控制台传回的信息内容反馈给服务器
          sk.send(std_out)
          sk.send(std_err)
          print('控制台输出的信息内容已经反馈')
          
          #接收服务器反馈的信息
          info = sk.recv(1024).decode('utf-8')
          print(info)
          
          #关闭客户端
          sk.close()
  • 相关阅读:
    pytest文档29-allure-pytest(最新最全,保证能搞成功!)
    使用 JMeter 进行压力测试
    web自动化针对PO模式进行二次封装之basepage
    关于面试总结-http协议相关面试题 -----转载
    移动APP测试基础分享
    基于python+requests+unittest框架接口自动化测试设计开发
    jmeter断言接口响应字段大小
    csv文件转换为xlsx文件
    钉钉机器人发群消息笔记
    docker学习笔记
  • 原文地址:https://www.cnblogs.com/liliudong/p/9732469.html
Copyright © 2020-2023  润新知