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
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...
- 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'
-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'))
-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
- 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'))
-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