tcp protocol and packet sticking in network programming

tcp protocol and socket in network programming

I. single supplement

  • Several ways to realize single column
#Mode 1: classmethod

# class Singleton:
#
#     __instance = None
#
#     @classmethod
#     def singleton(cls):
#
#         if not cls.__instance:
#             cls.__instance = cls()
#
#         return cls.__instance
#
# obj1 = Singleton.singleton()
# obj2 = Singleton.singleton()
# print(obj1)
# print(obj2)
# <__main__.Singleton object at 0x000002127F230D08>
# <__main__.Singleton object at 0x000002127F230D08>


#Mode 2: "new"__
# class Singleton:
#
#     __instance = None
#
#     def __new__(cls, *args, **kwargs):
#
#         if not cls.__instance:
#             cls.__instance = object.__new__(cls)
#
#         return cls.__instance
#
# obj1 = Singleton()
# obj2 = Singleton()
# print(obj1)
# print(obj2)
# <__main__.Singleton object at 0x00000257AAE10A88>
# <__main__.Singleton object at 0x00000257AAE10A88>


#Mode 3: decorator
# def singleton(cls):  #cls---> Father
#
#     __instance = {}
#
#     def inner(*args, **kwargs):
#         if cls not in __instance:
#             obj = cls(*args, **kwargs)
#             __instance[cls] = obj
#
#
#         return __instance[cls]
#     return inner
#
# @singleton
# class Father:
#     pass
#
# print(Father())
# print(Father())
# <__main__.Father object at 0x000001F17EB21548>
# <__main__.Father object at 0x000001F17EB21548>



#Mode four
//First, define a py file of Singletoncls as follows:
class Singletoncls:
    pass

obj = Singletoncls()
# from Singletoncls import obj
# print(obj)
# from Singletoncls import obj
# print(obj)
# from Singletoncls import obj
# print(obj)
# <Singletoncls.Singletoncls object at 0x00000249CD25BE48>
# <Singletoncls.Singletoncls object at 0x00000249CD25BE48>
# <Singletoncls.Singletoncls object at 0x00000249CD25BE48>

# Mode 5: metaclass

tcp protocol and packet sticking

  • Theoretical knowledge
Transport layer:
    -tcp protocol
    -udp protocol
    port: identifies a piece of software on a computer.
        -0-1024: prohibited because the operating system is using
        -8000 --- to be used later

    -Do not touch the fixed ports of the following software:
        django:8000
        mysql:3306
        redis:6379
        flask:5000
        tomcat:8080
        mongodb:27017
        ...
    To transfer data, a two-way channel must be established


1. tcp protocol: three handshakes, four waves
    -Establishing two-way channel by tcp protocol

    -Three handshakes, key connection:
        1: the client sends a connection request to the server
        2: the server returns the received request information to the client and sends it to the client to establish the request
        3: the client receives the request from the server, returns the request to the server successfully, and completes the two-way connection


    -Feedback mechanism:
        The client sends a request to the server, and the server must return a response
        Tell the client that it has received the request, and return the data of the server to the client
        C -- > s: one request, one response required

        - disadvantages:
            -Flood attack:
                It refers to sending requests to the opposite server by forging a large number of requests
                Cause the other server can't keep up, so it's paralyzed.
                Linux system has a parameter that can be limited

            -Semi connection pool listen: limit the number of users' access in the same time period

    -Four waves, disconnected
        1: the client sends the disconnected request to the server
        2: the server returns the requested information to the client
        3: after the server confirms the completion of all data reception, it will send the request for consent to disconnect to the client
        4: the client returns the disconnected request to the server

2. socket communication:
    -What is socket?
        Socket is a module, also known as socket, used to encapsulate Internet Protocol (the layer below application layer)

    -Why socket?
        socket can realize the work under the application layer of Internet Protocol
        -Improve development efficiency

    -How to use socket?
        import socket
        Write socket socket:
            client
            sever

3. Sticking
    -1) problem: unable to confirm the size of the data sent by the other party

    -2) problem: when the data transmission interval is short and the amount of data is small, all data will be sent at one time

    Solution: confirm the size of the opposite party's data

4. Solve the sticking problem (struct module)
    -No matter which piece of data is sent
        - client
            -1) first make the header and send it (struct)
            -2) send real data

        Server side
            -1) receive the header and unpack to obtain the real data length
            -2) receive real data according to the length of real data
            recv (real data length)

Socket socket

  • Socket socket basic version
  • Demonstration
-sever:
    
'''
//Start the socket server first
'''

import socket

#Buy cell phone
sever = socket.socket()

#Binding mobile card
sever.bind(
    ('127.0.0.1', 9876)
)

#Half connection pool
sever.listen(5)  #At most five people sit in the chair at the same time, actually = = 6

print(
    'Server is running...'
)

#Waiting for phone access
#coon: refers to the channel from the server to the client
coon, addr = sever.accept()

#What to say
#Messages sent by data client
data = coon.recv(1024) #1024bytes of data is acceptable at one time
print(data)

>>>Server is running...
>>>b'hello'

#Hang up the phone
coon.close()


-client:
'''
//Start the server first and then the client
'''

import socket

#Buy cell phone
client = socket.socket()

#Call up
client.connect(
    ('127.0.0.1', 9876)
)

print('Client running...')

#Data of type bytes must be sent
#Begin to speak
client.send(b'hello')
# Or client. Send ('Hello '. Encode ('utf? 8'))
>>>Client running...
  • Socket socket upgrade
- sever

'''
//Be careful:
    //If the client sends the message once, my server must accept it once before sending the message to the client
'''

import socket

#Buy cell phone
sever = socket.socket()

#Binding mobile card
#It's bound with a ancestor
sever.bind(
    ('127.0.0.1', 9876)
)


#Half connection pool
sever.listen(5)

print('Server is waiting for service...')

#Waiting for phone access
#coon: refers to the channel from the server to the client

coon, addr = sever.accept()

#What to say
data = coon.recv(1024)
print(data)

#Server sends message to client
coon.send(b'hi i am sever')

#Hang up the phone
coon.close()

>>>Server is waiting for service...
>>>b'hello i am client...'


- client
'''
//Start the server and then the client
'''
import socket

#Buy cell phone
client = socket.socket()

#dial
client.connect(
    ('127.0.0.1', 9876)
)

print('Client sending request...')

client.send(b'hello i am client...')

#Receive requests from the server
data = client.recv(1024)

print(data)

client.close()
>>>Client sending request...
>>>b'hi i am sever'
  • Socket socket advanced
-sever

import socket

#Buy cell phone
sever = socket.socket()


#Binding mobile card
sever.bind(
    ('127.0.0.1', 9876)
)

#Half connection pool
sever.listen(5)

print('Server is running...')

#Waiting for phone access
coon, addr = sever.accept()

while True:
    #Receive the content of the other party's speech
    #Messages sent by data client
    data = coon.recv(1024)
    if len(data) == 0:
        break
    if data.decode('utf-8') == 'q':
        break
    print(data.decode('utf-8'))

    send_data = input('Server side...')

    coon.send(send_data.encode('utf-8'))

#Hang up the phone
coon.close()
//Server running
//Service end... Hello, Yafeng

-client

import socket

#Buy cell phone
client = socket.socket()

#Call up
client.connect(
    ('127.0.0.1', 9876)
)

print('Client sending request...')

while True:
    send_data = input('Client>>>:').strip()
    client.send(send_data.encode('utf-8'))
    data = client.recv(1024)
    if data.decode('utf-8') == 'q':
        break
    if len(data) == 0:
        break

    print(data.decode('utf-8'))

client.close()
>>>Client sending request...
>>>Client>>>:Hello, Reba
>>>Okay, Ya Feng.
  • Socket socket final version
- sever


import socket

Buy mobile phone
sever = socket.socket()

#Binding mobile card
sever.bind(
    ('127.0.0.1', 9876)
)

#Semi connected pool
sever.listen(5)

print('server is serving... ')

#Loop implementation can be accessed by multiple users
while True:

    coon, addr = sever.accept()
    print(addr)

    #Circular communication
    while True:
        try:
            #Is there any exception in the listening code
            #What to say
            #Messages sent by data client
            data = coon.recv(1024)

            if len(data) == 0:
                break

            if data.decode('utf-8') =='q':
                break

            print(data.decode('utf-8'))

            send_data = input('server > >... ')

            #Server sends message to client
            coon.send(send_data.encode('utf-8'))

        except Exception as e:
            print(e)
            break

    Hang up the phone
    coon.close()

>>>
Server is serving
('127.0.0.1', 52467)
I'm looking for dirieba
 Hello, Yafeng. I'm Reba. Can I help you
 You are beautiful
 Thank you Yafeng


-client

import socket

Buy mobile phone

client = socket.socket()

#Dial number
client.connect(
    ('127.0.0.1', 9876)
)

print('Client is sending request... ')

while True:
    send_data = input('Client > >: ')
    client.send(send_data.encode('utf-8'))
    data = client.recv(1024)

    if data.decode('utf-8') == 'q':
        break

    if len(data) == 0:
        break

    print(data.decode('utf-8'))
>>>
client.close()
Client sending request
 Client > >: I want to find hot bar
 Hello, Yafeng. This is Reba. Can I help you
 Client > >: you are beautiful
 Thank you, Ya Feng.
Client > >:

IV. sticking

  • The appearance and several situations of sticking package problem
  • First question
-sever
#Question 1: do not know the specific length of data
# import socket
#
# import subprocess
#
# #Buy cell phone
# sever = socket.socket()
#
# #Binding phone card
# sever.bind(
#     ('127.0.0.1', 9867)
# )
#
# #Half integer pool
# sever.listen(5)
#
# while True:
#     coon, addr = sever.accept()
#     print(addr)
#
#     while True:
#         try:
#             #recv getting data from memory
#             cmd = coon.recv(1024)
#
#             if len(cmd) == 0:
#                 continue
#             cmd = cmd.decode('utf-8')
#             if cmd == 'q':
#                 break
#
#             #Call subprocess to connect the terminal, operate the terminal, and obtain the correct or wrong results after the operation
#             obj = subprocess.Popen(
#                 cmd, shell=True, stdout=subprocess.PIPE,
#                 stderr=subprocess.PIPE
#             )
#             #The result is given to the result variable name
#             result = obj.stdout.read() + obj.stderr.read()
#             print(len(result))
#
#             #gbk is the default for windows
#             print(result.decode('gbk'))
#
#             #Return the result to the client
#             coon.send(result)
#         except Exception as e:
#             print(e)
#             break
#
#     coon.close()


-client
# import socket
#
# client = socket.socket()
#
# client.connect(
#     ('127.0.0.1', 9867)
# )
#
# while True:
#
#     cmd = input('Client input: ')
#
#     client.send(cmd.encode('utf-8'))
#
#     data = client.recv(19190)
#
#     print(len(data))
#
#     print(data.decode('gbk'))
  • Second question
-sever

#Problem 2: when the length of the data sent in multiple times is not very long, the server receives the content received after multiple times

import socket

sever = socket.socket()

sever.bind(
    ('127.0.0.1', 9000)
)

sever.listen(5)

coon, addr = sever.accept()

data = coon.recv(10)
print(data)

data = coon.recv(1024)
print(data)

data = coon.recv(1024)
print(data)
>>>b'hellohello'
>>>b'hello'
>>>b''


- client
#Question two
import socket

client = socket.socket()

client.connect(
    ('127.0.0.1', 9000)
)

client.send(b'hello')
client.send(b'hello')
client.send(b'hello')

V. solve the sticking problem

  • Demonstration
- sever

import socket
import subprocess
import struct

sever = socket.socket()

sever.bind(
    ('127.0.0.1', 9000)
)

sever.listen(5)

while True:
    coon, addr = sever.accept()
    print(addr)

    while True:
        try:

            #Get the header from the client
            header = coon.recv(4)

            #Unpack to get the real data length
            data_len = struct.unpack('i', header)[0]

            #Prepare to receive real data
            cmd = coon.recv(data_len)

            if len(cmd) == 0:
                continue

            cmd = cmd.decode('utf-8')

            if cmd == 'q':
                break

            #Call subprocess to connect the terminal, operate the terminal, and get the correct or wrong results after the operation
            obj = subprocess.Popen(
                cmd, shell=True,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE
            )

            #The result is given to the result variable name
            result = obj.stdout.read() + obj.stderr.read()

            print('True length sent to client', len(result))

            #Return the result to the client, make a header and return it to the client
            header = struct.pack('i', len(result))
            print(len(header))
            coon.send(header)
            coon.send(result)

        except Exception as e:
            print(e)
            break

    coon.close()
    
    
- client


import struct
import socket

client = socket.socket()

client.connect(
    ('127.0.0.1', 9000)
)

while True:

    cmd = input('Client input:')

    cmd_bytes = cmd.encode('utf-8')

    #Make a headline
    header = struct.pack('i', len(cmd_bytes))

    print(len(header))

    client.send(header)

    #Wait for the server to confirm the length before sending the real data length
    client.send(cmd_bytes)

    #Receive the header returned by the server
    s_header = client.recv(4)

    #Unpack and receive the real data returned by the server
    data_len = struct.unpack('i', s_header)[0]

    result = client.recv(data_len)

    print('Real data length returned by receiving server', len(result))
    print(result.decode('gbk'))
  • Demo two
-sever

import socket
import struct
import json

sever = socket.socket()

sever.bind(
    ('127.0.0.1', 9000)
)

sever.listen(5)

while True:

    coon, addr = sever.accept()
    print(addr)

    while True:
        try:
            #Get the header from the client
            header = coon.recv(4)

            #Unpack to get the real data length
            json_len = struct.unpack('i', header)[0]

            #The actual length of the received json (dictionary)
            json_bytes_data = coon.recv(json_len)

            #Deserialization turns byte type data into json data
            json_data = json_bytes_data.decode('utf-8')

            back_dic = json.loads(json_data)
            print(back_dic)
            print(back_dic.get('movie_len'))

        except Exception as e:
            print(e)
            break

    coon.close()
    
>>>('127.0.0.1', 53414)
>>>{'movie_name': 'Lust Caution', 'movie_len': 100000}
>>>100000


-client
import struct
import socket
import json

client = socket.socket()

client.connect(
    ('127.0.0.1', 9000)
)

while True:

    movie_name = input('Please enter the name of the uploaded movie:').strip()

    #Camouflage movie real data
    movie_len = 100000

    send_dic = {
        'movie_name': movie_name,
        'movie_len': movie_len
    }

    #serialize
    json = json.dumps(send_dic)
    # print(json)
    # print(json.encode('utf-8'))
    # print(len(json.encode('utf-8')))

    json_bytes = json.encode('utf-8')

    #Make a headline
    header = struct.pack('i', len(json_bytes))

    #Sending header
    client.send(header)

    #Send real data
    client.send(json_bytes)

>>>Please input the name of the uploaded movie: lust, caution

Keywords: Python socket JSON Mobile shell

Added by nawhaley2265 on Mon, 09 Dec 2019 16:12:26 +0200