• Day 24 Network Programming


    Day 24 Network Programming

     

    一 TCP sockets

    As you’ll see shortly, we’ll create a socket object using socket.socket() and specify the socket type as socket.SOCK_STREAM. When you do that, the default protocol that’s used is the Transmission Control Protocol (TCP). This is a good default and probably what you want.

    • Is reliable: packets dropped in the network are detected and retransmitted by the sender.

    • Has in-order data delivery: data is read by your application in the order it was written by the sender.

    In contrast, User Datagram Protocol (UDP) sockets created with socket.SOCK_DGRAM aren’t reliable, and data read by the receiver can be out-of-order from the sender’s writes.

    Why is this important? Networks are a best-effort delivery system. There’s no guarantee that your data will reach its destination or that you’ll receive what’s been sent to you.

    The left-hand column represents the server. On the right-hand side is the client.

    Starting in the top left-hand column, note the API calls the server makes to setup a “listening” socket:

    socket() bind() listen() accept()

    A listening socket does just what it sounds like. It listens for connections from clients. When a client connects, the server calls accept() to accept, or complete, the connection.

    The client calls connect() to establish a connection to the server and initiate the three-way handshake. The handshake step is important since it ensures that each side of the connection is reachable in the network, in other words that the client can reach the server and vice-versa. It may be that only one host, client or server, can reach the other.

    In the middle is the round-trip section, where data is exchanged between the client and server using calls to send() and recv().

    At the bottom, the client and server close() their respective sockets.

    二 Sticky package

    Sticky package and sticky package solution of python Packet sticking mainly occurs in TCP connection. When a socket client based on TCP uploads a file to the server, the content of the file is sent according to a segment of byte stream. In the eyes of the receiver, it doesn't know where the byte stream of the file starts or ends at all

    There are two kinds of sticking phenomenon:

    1 consecutive packets may be sent together by optimization algorithm

    2 if the first time the size of the data sent is 2000B, and the receiving end accepts the size of 1024 at one time, the rest of the content will be received by the next recv, resulting in confusion of the results

    三 Solutions to the sticky phenomenon

    Scheme 1:

    because both parties don't know the length of the data sent by the other party, they may not receive completely or receive the information content sent in another time. Therefore, before sending the real data, the length of the data should be sent first. The receiving end receives the real data according to the length, but both parties have a process of mutual confirmation

    # Server side
    import socket
    import subprocess
    server = socket.socket()
    ip_port = ('127.0.0.1',8001)

    server.bind(ip_port)

    server.listen()

    conn,addr = server.accept()

    while 1:
      from_client_cmd = conn.recv(1024)

      print(from_client_cmd.decode('utf-8'))
      #Receiving system instructions from the client,My server passes subprocess The module executes this instruction in the server's own system
      sub_obj = subprocess.Popen(
          from_client_cmd.decode('utf-8'),
          shell=True,
          stdout=subprocess.PIPE, #Where to store the correct results
          stderr=subprocess.PIPE   #Storage location of error results
      )
      #Take the results out of the pipe,adopt subprocess.Popen Instanced objects for.stdout.read()Method to get the results in the pipeline
      std_msg = sub_obj.stdout.read()

      #In order to solve the sticking phenomenon,We counted the length of the message,Send the length of the message to the client first,The client receives the real data to be sent later through this length
      std_msg_len = len(std_msg)
      # std_bytes_len = bytes(str(len(std_msg)),encoding='utf-8')
      #First, convert the data type of data length to bytes type
      std_bytes_len = str(len(std_msg)).encode('utf-8')
      print('Execution result length of instruction>>>>',len(std_msg))
      conn.send(std_bytes_len)

      status = conn.recv(1024)
      if status.decode('utf-8') == 'ok':

          conn.send(std_msg)
      else:
          pass
    # Client
    import socket

    client = socket.socket()
    client.connect(('127.0.0.1',8001))

    while 1:
      cmd = input('Please input the instruction:')
      client.send(cmd.encode('utf-8'))

      server_res_len = client.recv(1024).decode('utf-8')
      print('Message length from server',server_res_len)

      client.send(b'ok')

      server_cmd_result = client.recv(int(server_res_len))
      print(server_cmd_result.decode('gbk'))

    Scheme 2:

    Struct module,

    Package: struct.pack('i ', length)

    Unpack: struct.unpack('i ', bytes)

    # Server side
    import socket
    import subprocess
    import struct
    server = socket.socket()
    ip_port = ('127.0.0.1',8001)

    server.bind(ip_port)

    server.listen()

    conn,addr = server.accept()

    while 1:
      from_client_cmd = conn.recv(1024)

      print(from_client_cmd.decode('utf-8'))
      #Receiving system instructions from the client,My server passes subprocess The module executes this instruction in the server's own system
      sub_obj = subprocess.Popen(
          from_client_cmd.decode('utf-8'),
          shell=True,
          stdout=subprocess.PIPE, #Where to store the correct results
          stderr=subprocess.PIPE   #Storage location of error results
      )
      #Take the results out of the pipe,adopt subprocess.Popen Instanced objects for.stdout.read()Method to get the results in the pipeline
      std_msg = sub_obj.stdout.read()

      #In order to solve the sticking phenomenon,We counted the length of the message,Send the length of the message to the client first,The client receives the real data to be sent later through this length
      std_msg_len = len(std_msg)

      print('Execution result length of instruction>>>>',len(std_msg))
      msg_lenint_struct = struct.pack('i',std_msg_len)
      conn.send(msg_lenint_struct+std_msg)
    # Client
    import socket
    import struct
    client = socket.socket()
    client.connect(('127.0.0.1',8001))

    while 1:
      cmd = input('Please input the instruction:')
      #Send instruction
      client.send(cmd.encode('utf-8'))

      #Received data length,Receive 4 bytes of data first,Because these four bytes are length
      server_res_len = client.recv(4)
      msg_len = struct.unpack('i',server_res_len)[0]

      print('Message length from server',msg_len)
      #Length by unpacking,To receive the real data
      server_cmd_result = client.recv(msg_len)
      print(server_cmd_result.decode('gbk'))

     

  • 相关阅读:
    Thinkphp 中的自动验证 上一篇有例子
    Thinkphp框架 表单自动验证登录注册 ajax自动验证登录注册
    ThinkPHP框架 祖辈分的理解 【儿子 FenyeController】继承了【父亲 FuController】继承了【祖辈 Controller】的
    ThinkPHP框架 AJAX方法返回 AJAX实现分页例子:
    ThinkPHP框架 【 AJAX方法返回 】 例子:简单添加一条数据 和 查询一个表里的数据
    thinkPHP框架 简单的删除和修改数据的做法 和 模板继承的意思大概做法
    cookie 和 session 的区别
    ThinkPHP框架 表单传值自动验证!!
    UVA 11624 Fire! (bfs)
    POJ 3074 Sudoku (Dacing Links)
  • 原文地址:https://www.cnblogs.com/fengshili666/p/14295578.html
Copyright © 2020-2023  润新知