Summary of Network Programming

Posted by FRSH on Sat, 17 Aug 2019 10:58:56 +0200

Catalog

1.C/S B/S Architecture

C/S B/S Architecture
 C: client side
 B: browse browser
 S: server side
 C/S Architecture: Based on Communication between Client and Server
 QQ, game, shrimp, quick hand, tremble.
Advantages: Personalized settings, fast response speed,
Disadvantages: high development cost, high maintenance cost, occupied space, fixed users.
B/S Architecture: Communication between Browser and Server
 Google Browser, 360 Browser, Firefox Browser and so on.
Advantages: Low cost of development and maintenance, relatively low occupancy of space, users are not fixed.
Disadvantage: Single function, no personalized settings, relatively slow response speed.

2. Principle of Network Communication

In the 1980s, fixed telephone contacts (Putonghua hasn't been promoted yet)
1. A bunch of physical connection media is connected between two telephones.
2. Dial up and lock the location of the other party's phone.
Since there was no unified Putonghua at that time, if you had friendly communication with friends from Henan, Shanxi, Guangxi and Fujian, you had to learn the local dialect.

Promote Putonghua and unify the way of communication.
1. A bunch of physical connection media is connected between two telephones.
2. Dial up and lock the location of the other party's phone.
3. Unify the way of communication.

Global communication:
1. A bunch of physical connection media is connected between two telephones.
2. Dial up and lock the location of the other party's phone.
3. Unified mode of communication. (English)

Turn back to Internet communications:
Now I want to contact a girl in the United States. How do you use computers to connect???
1. Two computers need a bunch of physical connection media.
2. Find the software location of each other's computer.
3. Follow a package of Internet communication protocols.

3.osi seven-tier protocol

  1. Simple Series Five-Layer Protocol and Its Function

    1. physical layer

      Physical layer refers to the physical connection media such as mesh, optical fiber, twisted pair and so on.
      
      What the physical layer sends is the bit stream: 010101010101010101010101 is just sending the bit stream. What's the problem???
      
      Data should be grouped regularly, and grouping is what the data link layer does.
    2. data link layer

      Data link layer grouping bit stream.
      At first, several companies in the United States were engaged in the Internet business, each with its own grouping standards. Later, the standard was unified: the standard of data grouping.
      
      ** Ethernet Protocol**: Reasonable grouping of bitstream.
      A set of data 01010101 is called a frame, a datagram.
      Head | data (night appointment)
      
      head is fixed length: 18 bytes
       Source address: 6 bytes   
      Target address: 6 bytes 
      Data type: 6 bytes
      
      data: At least 46 bytes, up to 1500 bytes.
      One frame of data: minimum 64 bytes, maximum 1518 bytes.
      One frame of data | One frame of data...
      Each computer has a network card that records a unique address.
      
      ** mac Address **: That's the address marked on your computer's Internet card.
      12-bit hexadecimal number composition: the first six is the manufacturer number, the last six is the pipeline number.
      Source mac address target mac address data type | data
      '1C-1B-0D-A4-E6-44'
      Computer communication mode:
      In the same LAN, it communicates by broadcasting.
      
      Once the message is broadcast, all the people in the village (all computers in the LAN can receive the message, analyze the message, whether they are looking for me or not, they will discard it).
      Computers can only broadcast in local area networks: broadcasting storms are widespread and inefficient.
      There are two unresolved issues:
      1. How do different LANs communicate?
      2. Communication between software and software, not between computers.
      Supplement:
          The same LAN transmits data in the form of broadcasting.
          mac Address Learning Function of Switch:
          Five interfaces of a switch: five computers.
           1: FF-FF-FF-FF-FF-FF
           2: FF-FF-FF-FF-FF-FF
           3: FF-FF-FF-FF-FF-FF
           4: FF-FF-FF-FF-FF-FF
           5: FF-FF-FF-FF-FF-FF
          Interface 1: Source mac 1C-1B-0D-A4-E6-44 Target 1C-1C-0D-A4-E5-44 | Data is broadcast
          2,3,4,5 ports will receive messages, 5 ports will be the final destination address, and the switch will correspond 5 ports to the mac address.
           1: 1C-1B-0D-A4-E6-44
           2: FF-FF-FF-FF-FF-FF
           3: FF-FF-FF-FF-FF-FF
           4: FF-FF-FF-FF-FF-FF
           5: 1C-1C-0D-A4-E5-44
          When the five ports correspond to the specific mac address, and two ports send messages again, they will not broadcast, they will be sent unicast.
          What is our premise? You must know the mac address of the other party before you can send messages in the form of broadcasting. In fact, in network communication, you only need to know the IP of the other party and your own IP.
    3. network layer

      ** IP Protocol**: Location of Local Area Network (Subnet)
      Find the location of specific software, the top level of things
          IP protocol: 
              ip address: four-segment decimal 192.168.0.12  
              The range of values is 0-255.0-255.0-255.0-255.0-255.0-255.
              Subnet mask: Class C subnet mask: 255.255.255.0
              ip address + subnet mask is calculated by bit and operation whether it is in the unified local area network (subnet, segment).
              Calculations 172.16.10.1 and 172.16.10.128
              ​    172.16.10.1: 10101100.00010000.00001010.00000001
              255.255.255.0:   11111111.11111111.11111111.00000000
              Subordinate LAN: 172.16.10.0
              172.16.10.128: 10101100.00010000.00001010.10000000
              255.255.255.0:   11111111.11111111.11111111.00000000
              Subordinate LAN: 172.16.10.0
              172.16.10.1 ~172.16.10.255
              Class C subnet masks can carry more than one IP address per segment?
              172.16.10.0 was occupied.
              172.16.10.255 broadcasting address occupied.
              172.16.10.1 was occupied.
              253 computers.
              If you want to send data to another computer, you must know the ip address of the other computer.
              ** ARP Protocol**: Get the mac address of the other party through the ip address of the other party.
            Source mac target mac source IP target IP data
              1C-1B-0D-A4-E6-44 FF: FF: FF: FF: FF: FF: FF: FF: 172.16.10.13 172.16.10.156 data
      
              First message: sent to switch - > router broadcast
              Target computer receives message: Return message:
               Source mac target mac source IP target IP data
              1B-1B-0D-A4-E6-541C-1B-0D-A4-E6-44 172.16.10.156 172.16.10.13 Data
      Summary:
          Prerequisite: Know the target mac:
          Computer A sends a message to Computer B 
          Source mac target mac source IP target IP data
          Unicast is sent to the switch, and the switch detects if its control table has a target mac, and if so, unicast. If not, send it to the upper layer: router:
          The router receives the message: analyze the message: 
          To determine whether the target computer and the computer are in the same network segment,
          If the switch is sent directly to the corresponding switch in the same network segment, the switch is unicast to the target mac.
          If not in the same segment:
      
          Premise: do not know the target mac:
          Computer A sends a message to Computer B 
          Source mac target mac does not know source IP target IP data
          Unicast is sent to the switch, which is handed over to the upper router: the router receives the message: analyze the message: 
          To determine whether the target computer and the computer are in the same network segment,
          If the mac address of the other party is acquired through IP and ARP protocol in the same network segment, then it is communicated.
          If not in the same segment:
    4. transport layer

      Port Protocol: Determine the Software Location on the Computer
      Port Protocol: UDP Protocol, TCP Protocol
       Port 65535
       Ports for 1-1024 Operating System
       Example: 3306 database
       Self-developed software is the port number after 8080
    5. application layer

      Self-defined protocols
      
      Broadcasting (in LAN) + mac address (computer location) + IP (LAN location) + port (software location in computer)
      With these four parameters, you can locate the software of any computer in the world.
  2. The next day's review

    Unicast: Contact a person individually
     Broadcasting: Sending messages to everyone (mass distribution)
    bit Stream: bit is 0101 sending 0101001 in the same stream as water.
    Ethernet protocol: Grouping data: a set of data called a frame, datagram.
    ​    head | data
     head: 18 bytes: source mac address | target mac address | data type
     data: At least 46 bytes, up to 1500 bytes
     mac address: the address recorded on the computer network card, the unique identification of all computers in the world, used for locating computers when broadcasting (unicast) in the local area network
     Switches: the role of shunting computers
     Router: Home Router and Enterprise Router
    
    
    mac learning function of switch:
    When the learning table records the corresponding relationship between the port and the mac address, it sends the message in the form of unicast.
    Port 1: 1C-5F-4B-3E-35-2C
     Port 2: 1C-5F-4B-6E-35-2C
    
    Broadcasting Storm: All computers send messages in the form of broadcasting.
    IP Protocol: Four-segment decimal system
    ​    172.168.0.1
    
    Subnet mask:
    ​    A: 255.0.0.0
    ​    B: 255.255.0.0
    ​    C: 255.255.255.0
    
    Router: 
    Extranet (public network) IP, 
    Intranet (LAN) IP is fake, DHCP protocol: IP address automatically distributed by router, gateway and so on.
    
    
    Port: 0-1023 system, you can choose port 8080 later.
    ARP protocol: Get mac address of computer through IP.
    TCP protocol: Link-oriented protocol, streaming protocol, secure, reliable and inefficient protocol, file transfer, browser, etc.
    UDP Protocol: User Data Reporting Protocol, High Efficiency, Unreliable Protocol, Wechat
    
    Three shakes and four waves:

4.UDP TCP Protocol

TCP (Transmission Control Protocol) is a reliable, connection-oriented protocol (eg: call), streaming protocol, low transmission efficiency full-duplex communication (send-cache-receive-cache), byte-stream oriented. Applications using TCP: Web browser; file transfer program.

UDP (User Data gram Protocol) is an unreliable and connectionless service, with high transmission efficiency (low delay before sending), one-to-one, one-to-many, many-to-one, many-to-many, message-oriented (data package), best service and no congestion control. Applications using UDP: Domain Name System (DNS); Video Stream; Vo IP.

5. Three Handshakes and Four Waves of TCP Protocol

syn Flood Attack: Creates a large number of false and invalid IP request servers. This prevents normal IP from accessing the servers.

6.socket socket

Socket socket:
    1.socket is an abstract layer between the application layer and the transport layer. It is a set of very simple interfaces (accepting data) which are handed over to the operating system after accepting data.
    Why is there a socket abstraction layer?
    If directly interacting with the operating system data is very cumbersome and cumbersome, socket encapsulates these cumbersome operations to a high degree and simplifies them.
    2.socket is a module in python.

7. Simple socket communication based on TCP protocol

# Server

import socket

phone = socket.socket()

phone.bind(('192.168.14.230', 8849))

phone.listen(2)  # listen allows several people to link, and the rest of the links wait

conn, addr = phone.accept()  # Waiting for the client to connect to me, in blocked state
print(f'Here comes the link.{conn,addr}')


from_client_data = conn.recv(1024)
print(f'From the client{addr}news:{from_client_data.decode("utf-8")}')

to_client_data = input('>>>').strip().encode('utf-8')
conn.send(to_client_data)
conn.close()
phone.close()
# Client
import socket
phone = socket.socket()

phone.connect(('192.168.14.230', 8849))

to_server_data = input('>>>').strip().encode('utf-8')
phone.send(to_server_data)

from_server_data = phone.recv(1024)
print(f'Messages from the server:{from_server_data}')

8. socket Loop Communication Based on TCP Protocol

Summary:
    Both the server and the client add loops. If both sides break directly after normal exit, set judgment information.
    The server adds a while loop after the client waits for the connection, and the client adds a loop after the link address.
    The server needs to add an exception handling to the exception exit to prompt the exception exit.
# Server
import socket

phone = socket.socket()

phone.bind(('192.168.14.230', 8849))

phone.listen(2)  # listen allows several people to link, and the rest of the links wait

conn, addr = phone.accept()  # Waiting for the client to connect to me, in blocked state
print(f'Here comes the link.{conn,addr}')

while 1:
    try:
        from_client_data = conn.recv(1024)

        if from_client_data.upper() == b'Q':  # The normal exit server is then shut down
            print('Customers quit chatting normally')
            break

        print(f'From the client{addr}news:{from_client_data.decode("utf-8")}')
        to_client_data = input('>>>').strip().encode('utf-8')
        conn.send(to_client_data)
    except ConnectionResetError:  # Exceptional exit will result in an error writing prompt
        print('Client link broken')
        break

conn.close()
phone.close()
# Client
import socket
phone = socket.socket()

phone.connect(('192.168.14.230', 8849))

while 1:
    to_server_data = input('>>>').strip().encode('utf-8')
    if not to_server_data:  # If the server receives empty content, the server will be blocked all the time. No matter which end sends it, it can't be empty.
        print('Sending content cannot be empty')
        continue

    phone.send(to_server_data)
    if to_server_data.upper() == b'Q':  # Judging if Q, quit and quit normally
        break

    from_server_data = phone.recv(1024)
    print(f'Messages from the server:{from_server_data}')
phone.close()

9. socket Link + Circular Communication Based on TCP Protocol

Summary:
    The server adds a layer of while loop before the client link and adds closing the call to the bottom of the loop.
    listen(2) allows two people to link, and the rest of the links wait (actually three people to link), and if they exceed, they will report an error.
    If the first link sends a message, the second one automatically receives the second message when the first one closes.
# Server
import socket

phone = socket.socket()  # Buy a telephone

phone.bind(('192.168.14.230', 8849))  # Port-bound telephone cards allocated by the system before 0-65535 1024

phone.listen(2)  # listen allows two people to link and the rest to wait (actually three people to link)

while 1:
    conn, addr = phone.accept()  # Waiting for the client to connect to me, in blocked state
    print(f'Here comes the link.{conn,addr}')

    while 1:
        try:
            from_client_data = conn.recv(1024)

            if from_client_data.upper() == b'Q':  # Normal exit client channel followed by closure
                print('Customers quit chatting normally')
                break

            print(f'From the client{addr}news:{from_client_data.decode("utf-8")}')
            to_client_data = input('>>>').strip().encode('utf-8')
            conn.send(to_client_data)
        except ConnectionResetError:  # Exceptional exit will result in an error writing prompt
            print('Client link broken')
            break
    conn.close()
phone.close()
# Client
import socket

phone = socket.socket()

phone.connect(('192.168.14.230', 8849))

while 1:
    to_server_data = input('>>>').strip().encode('utf-8')
    if not to_server_data:  # If the server receives empty content, the server will be blocked all the time. No matter which end sends it, it can't be empty.
        print('Sending content cannot be empty')
        continue

    phone.send(to_server_data)
    if to_server_data.upper() == b'Q':  # Judging if Q, quit and quit normally
        break

    from_server_data = phone.recv(1024)  # Maximum number of bytes accepted
    print(f'Messages from the server:{from_server_data}')

phone.close()

10. socket application example based on TCP protocol: execute remote commands

Summary:
    The server first imports the subprocess module to execute commands.
    Then change the receiving content to the fixed code of the operation command.
    Client receiving content needs to be changed to gbk encoding, because the default encoding of windows operating system is gbk encoding, and Apple system does not need to be changed.
    """
    shell: Command interpreter, which is equivalent to calling cmd to execute the specified command.
    stdout: The correct result is thrown into the pipe.
    stderr: Misplaced in another pipe.
    The default encoding for windows operating system is gbk encoding.
    """
# Server
import socket
import subprocess

phone = socket.socket()

phone.bind(('192.168.14.230', 8849))

phone.listen(2)  # listen allows two people to link, the rest of the links wait

while 1:
    conn, addr = phone.accept()  # Waiting for the client to connect to me, in blocked state
    print(f'Here comes the link.{conn,addr}')

    while 1:
        try:
            from_client_data = conn.recv(1024)

            if from_client_data.upper() == b'Q':  # Normal exit client channel followed by closure
                print('Customers quit chatting normally')
                break

            obj = subprocess.Popen(from_client_data.decode('utf-8'),
                                   shell=True,  # shell: Command interpreter, which is equivalent to calling cmd to execute the specified command.
                                   stdout=subprocess.PIPE,  # stdout: The correct result is thrown into the pipe.
                                   stderr=subprocess.PIPE,  # stderr: Misplaced in another pipe.
                                   )
            result = obj.stdout.read() + obj.stderr.read()

            conn.send(result)

        except ConnectionResetError:  # Exceptional exit will result in an error writing prompt
            print('Client link broken')
            break
    conn.close()
phone.close()
# Client
import socket

phone = socket.socket()

phone.connect(('192.168.14.230', 8849))

while 1:
    to_server_data = input('>>>').strip().encode('utf-8')
    if not to_server_data:  # If the server receives empty content, the server will be blocked all the time. No matter which end sends it, it can't be empty.
        print('Sending content cannot be empty')
        continue

    phone.send(to_server_data)
    if to_server_data.upper() == b'Q':  # Judging if Q, quit and quit normally
        break

    from_server_data = phone.recv(1024)  # Maximum number of bytes accepted
    print(f'Messages from the server:{from_server_data.decode("gbk")}')

phone.close()
Operating system cache:
    1. Why is there a buffer?
        1. Store some data temporarily.
        2. Buffer exists. If your network is fluctuating, make sure the data is sent and received stably and uniformly.
        Disadvantage: One of the sticky phenomena.

11. Sticking phenomenon

The first sticking phenomenon is:
    At the same time, receiving send many times and too little data each time will result in sticky packet phenomenon, because it is too fast to merge multiple times into one transmission.
    If you send your data several times in a row for a short time (the amount of data is very small), your data will be sent out uniformly.
The second sticky phenomenon is:
    The amount of send data received at one time is too large, resulting in incomplete reception at one time, and the second reception is the first remaining content.
    In-depth study of transceiver solutions
How to solve the sticking phenomenon:
    The way to solve the sticking phenomenon is as follows:
    The server sends 10000 bytes of data at a time. 
    When the client receives data, it receives 1024 bytes each time (up to) until all the bytes are received. The received data is spliced together and decoded finally.
    1. Problems encountered: The number of recv s cannot be determined
        Before you send me the total data, send me a long one.
        Degree: 5000 bytes. Then send the total data.
        Client: First receive a length. 5000 bytes.
        Then I recycle the recv control cycle only if the data you receive is less than 5000.
        
    2. Problems encountered: The length of the total data converted into a fixed number of bytes
        Server:
        conn.send(total_size)
        conn.send(result)
        Tot_size int type
        Client:
        total_size_bytes = phone.recv(4)
        total_size
        data = b''
        while len(data) < total_size:
            data = data + phone.recv(1024)
            
            
You need to convert the total_size int type to bytes type before you can send it
    387 - > str (387)'387'- > bytes b'387' length 3 bytes
    4185 - > str (4185)'4185'- > bytes b'4185' length 4 bytes
    18000--------------------------------------------------------------------------------------------> length 5 bytes
 We need to solve the following problems:
    Converts the fixed length int type to the fixed length bytes and can be flipped back.
Multiple Receiving Solves Sticky Packing Phenomenon,But it's not a fundamental solution.:
    
    from_client_data = conn.recv(3)  # Accept up to 1024 bytes
    print(f'From the client{addr}news:{from_client_data.decode("utf-8")}')

    from_client_data = conn.recv(3)  # Accept up to 1024 bytes
    print(f'From the client{addr}news:{from_client_data.decode("utf-8")}')

    from_client_data = conn.recv(3)  # Accept up to 1024 bytes
    print(f'From the client{addr}news:{from_client_data.decode("utf-8")}')

    from_client_data = conn.recv(3)  # Accept up to 1024 bytes
    print(f'From the client{addr}news:{from_client_data.decode("utf-8")}')

12.low Version Solves the Sticking Phenomenon

  1. The first kind of sticky package: when the send's data is too large, which is larger than the upper limit of the recv, the other party will receive the remaining data that was not recv completed in the last recv.
Import the struct module:
    Server produces fixed length header usage
    Client counter-decoding header usage
 Code experiment is effective:
    Server side:
        Tot_size = len (result) # View bytes
        print(f'total bytes: {total_size}')
        Head_bytes = struct. pack ('i', total_size) # 1. Make fixed length headers'I' and fix four headers
        Conn. send (head_bytes) # 2. Send fixed-length headers
        Conn. send (result) # 3. Send total data
    Client:
        Head_bytes = phone. recv (4) # 1. Receiving headers 
        Tot_size = struct. unpack ('i', head_bytes) [0] # 2. Countersolution header'i'fixes four headers
        Tot_data = b''# receives content and adds bytes type in turn. If only English, ASCII code can be omitted.
        While len (total_data) < total_size:  The length of the received content will not exceed the length of the reverse unpacking header, so use judgment
            Tot_data+= phone.recv(1024)# is originally a counter-header, which is then received directly and processed every 1024 until the end.
# Server
import socket
import subprocess
import struct

phone = socket.socket()

phone.bind(('192.168.14.230', 8849))

phone.listen(2)  # listen allows two people to link, the rest of the links wait

while 1:
    conn, addr = phone.accept()  # Waiting for the client to connect to me, in blocked state
    # print(f'link to {conn,addr}')

    while 1:
        try:
            from_client_data = conn.recv(1024)

            if from_client_data.upper() == b'Q':  # The normal exit server is then shut down
                print('Customers quit chatting normally')
                break

            obj = subprocess.Popen(from_client_data.decode('utf-8'),
                                   shell=True,  # shell: Command interpreter, which is equivalent to calling cmd to execute the specified command.
                                   stdout=subprocess.PIPE,  # stdout: The correct result is thrown into the pipe.
                                   stderr=subprocess.PIPE,  # stderr: Misplaced in another pipe.
                                   )
            result = obj.stdout.read() + obj.stderr.read()  # Receive correct or wrong commands

            total_size = len(result)  # View bytes
            print(f'Total bytes:{total_size}')

            head_bytes = struct.pack('i', total_size)  # 1. Making fixed length headers'i' fixing four headers

            conn.send(head_bytes)  # 2. Send fixed-length headers

            conn.send(result)  # 3. Send Total Data

        except ConnectionResetError:  # Exceptional exit will result in an error writing prompt
            print('Client link broken')
            break
    conn.close()
phone.close()
# Client
import socket
import struct

phone = socket.socket()

phone.connect(('192.168.14.230', 8849))

while 1:
    to_server_data = input('>>>').strip().encode('utf-8')
    if not to_server_data:  # If the server receives empty content, the server will be blocked all the time. No matter which end sends it, it can't be empty.
        print('Sending content cannot be empty')
        continue

    phone.send(to_server_data)
    if to_server_data.upper() == b'Q':  # Judging if Q, quit and quit normally
        break

    head_bytes = phone.recv(4)  # 1. Receiving headers

    total_size = struct.unpack('i', head_bytes)[0]  # 2. Anti-resolution headers'i' fix four headers

    total_data = b''  # Receive content, add bytes type in turn, if only English can not add ASCII code

    while len(total_data) < total_size:
        total_data += phone.recv(1024)

    print(len(total_data))
    print(total_data.decode('gbk'))

phone.close()

13.recv Working Principle

Source code interpretation:
Receive up to buffersize bytes from the socket. Receive byte data from the socket buffer.

For the optional flags argument, see the Unix manual. For the parameters of these settings, you can see the Unix manual.

When no data is available, block untilat least one byte is available or until the remote end is closed. When no data is available in the buffer, recv will remain blocked until at least one byte of data is available in the buffer or the remote end is closed.

When the remote end is closed and all data is read, return the empty string. Close the remote end and read all data, return the empty string.
Understand:
    Recv empty string: The client of the other side is closed, and the buffer of the server side has no data. I recv to empty bytes.
    1 Verify that the server-side buffer data has not been fetched, and recv execution is performed, recv will continue to fetch values.
    2 Verify that the server's buffer has been taken out and recv execution has been executed. At this time, recv is blocked if the client does not close within 20 seconds.
    3 Verify that the server-side buffer is empty and recv is executed. When the client is closed, recv will fetch an empty string.

14. Solution of sticking package in Gaoda Upper Edition (self-customized package head)

Server:
    1.Self-customized headers
        head_dic = {  
        'file_name': 'test1',  # File names that need to be manipulated. Use variables
        'md5': 987654321,  # md5 encryption of file bytes, check usage. variable
        'total_size': total_size,  # Total byte length
        }
    2.json Formal headlines
            head_dic_json = json.dumps(head_dic)
    3.bytes Formal headlines
            head_dic_json_bytes = head_dic_json.encode('utf-8')
    4.Obtain bytes The total number of bytes in the form of headers
            len_head_dic_json_bytes = len(head_dic_json_bytes)
    5.Unfixed int Total Byte Programming Fixed Length 4 Bytes
            four_head_bytes = struct.pack('i', len_head_dic_json_bytes)
    6.Send a fixed four bytes
            conn.send(four_head_bytes)
    7.Send header data
            conn.send(head_dic_json_bytes)  
    8.Send Total Data
            conn.send(result)

//Client:
    1.Receiving header
        head_bytes = phone.recv(4)
    2.Get bytes The total number of bytes in a type dictionary
        len_head_dic_json_bytes = struct.unpack('i', head_bytes)[0]
    3.Receive bytes Type dic data
        head_dic_json_bytes = phone.recv(len_head_dic_json_bytes)
    4.Conversion to json type dic
        head_dic_json = head_dic_json_bytes.decode('utf-8')
    5.Headers converted into Dictionaries
        head_dic = json.loads(head_dic_json)
# Server
import socket
import subprocess
import struct
import json

phone = socket.socket()

phone.bind(('192.168.14.230', 8849))

phone.listen(2)  # listen allows two people to link, the rest of the links wait

while 1:
    conn, addr = phone.accept()  # Waiting for the client to connect to me, in blocked state
    # print(f'link to {conn,addr}')

    while 1:
        try:
            from_client_data = conn.recv(1024)

            if from_client_data.upper() == b'Q':  # The normal exit server is then shut down
                print('Customers quit chatting normally')
                break

            obj = subprocess.Popen(from_client_data.decode('utf-8'),
                                   shell=True,  # shell: Command interpreter, which is equivalent to calling cmd to execute the specified command.
                                   stdout=subprocess.PIPE,  # stdout: The correct result is thrown into the pipe.
                                   stderr=subprocess.PIPE,  # stderr: Error thrown into another pipe.
                                   )
            result = obj.stdout.read() + obj.stderr.read()  # Receive correct or wrong commands

            total_size = len(result)  # byte
            print(f'Total bytes:{total_size}')  # View bytes

            head_dic = {  # 1 custom header
                'file_name': 'test1',  # File names that need to be manipulated. Use variables
                'md5': 987654321,  # md5 encryption of file bytes, check usage. variable
                'total_size': total_size,  # Total byte length
            }

            head_dic_json = json.dumps(head_dic)  # 2 json header

            head_dic_json_bytes = head_dic_json.encode('utf-8')  # 3 bytes form header

            len_head_dic_json_bytes = len(head_dic_json_bytes)  # 4 Gets the total number of bytes of headers in bytes form

            four_head_bytes = struct.pack('i', len_head_dic_json_bytes)  # 5 Programming 4 fixed-length bytes with a fixed total number of int s

            conn.send(four_head_bytes)  # 6 Send fixed 4 bytes

            conn.send(head_dic_json_bytes)  # 7 Send header data

            conn.send(result)  # 8 Send Total Data

        except ConnectionResetError:  # Exceptional exit will result in an error writing prompt
            print('Client link broken')
            break
    conn.close()
phone.close()
# Client
import socket
import struct
import json

phone = socket.socket()

phone.connect(('192.168.14.230', 8849))

while 1:
    to_server_data = input('>>>').strip().encode('utf-8')
    if not to_server_data:  # If the server receives empty content, the server will be blocked all the time. No matter which end sends it, it can't be empty.
        print('Sending content cannot be empty')
        continue

    phone.send(to_server_data)
    if to_server_data.upper() == b'Q':  # Judging if Q, quit and quit normally
        break

    head_bytes = phone.recv(4)  # 1. Receiving headers

    len_head_dic_json_bytes = struct.unpack('i', head_bytes)[0]  # 2 Get the total number of bytes in a bytes-type dictionary

    head_dic_json_bytes = phone.recv(len_head_dic_json_bytes)  # 3 Receive dic data of bytes type

    head_dic_json = head_dic_json_bytes.decode('utf-8')  # 4 converted to json type dic

    head_dic = json.loads(head_dic_json)  # 5 headers converted into Dictionaries

    '''
    head_dic = {
            head_dic = {  # 1 custom header
                'file_name': 'test1',  # File names that need to be manipulated. Use variables
                'md5': 987654321,  # md5 encryption of file bytes, check usage. variable
                'total_size': total_size,  # Total byte length
            }
    '''

    total_data = b''  # Receive content, add bytes type in turn, if only English can not add ASCII code

    while len(total_data) < head_dic['total_size']:  # The length of the received content will not exceed the length of the reverse decomposition header, so use judgment
        total_data += phone.recv(1024)  # It's the COUNTERSOLUTION of the header, then it receives all of it directly, and then it's processed every 1024 until the end.

    print(len(total_data))
    print(total_data.decode('gbk'))

phone.close()

15. socket Communication Based on UDP Protocol

1. The socket based on udp protocol does not need to establish a pipeline. It can open the server or client first.
2. A socket based on udp protocol receives a message and is disconnected from sending a message.
3. As long as you get my ip address and port, you can send me messages. I receive messages in sequence.

server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)  
Socket socket. SOCK_DGRAM based on UDP protocol
# Server
import socket

server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# socket Based on UDP Protocol
server.bind(('192.168.14.198', 9000))

while 1:
    from_client_data = server.recvfrom(1024)  # Blocking, waiting for customers to come
    print(f'\033[1;35;0m From the client{from_client_data[1]}: {from_client_data[0].decode("utf-8")} \033[0m')
    to_client_data = input('>>>').strip()
    server.sendto(to_client_data.encode('utf-8'), from_client_data[1])
    
    //Finally, if there is no comment, the receiver must reply once to continue receiving.
    //Two lines can be received indefinitely if they are commented and only accepted but not sent.
import socket

client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# socket Based on UDP Protocol

while 1:
    to_server_data = input('>>>:').strip()
    client.sendto(to_server_data.encode('utf-8'), ('127.0.0.1', 9000))
    data,addr = client.recvfrom(1024)
    print(f'from the server {addr} message: {data.decode("utf-8")}')
    
    Finally, if there is no comment, the reply must be received once before it can be answered again.
    If two lines are commented, they can be sent infinitely if they are sent or not received.

16. socketserver (to be talked about)

Topics: Python socket Mac network JSON