Network Programming Python- stick package, UDP

Stick package problem

What is the problem then stick package?

When we write tcp socket programming, tcp protocol is a streaming protocol, the data sent by the server for the first time, a one-time client can not accurately received, the next data sent with the last data stick together.

which is:

1, the data size can not predict the length of the other party needs to receive

2, a plurality of successive small amount of data transmitted, and the short time interval of data is transmitted together with a disposable package

TCP protocol features:

Multiple small amounts of data will continuously transmitted, and the short time interval of one-time data transmission is completed

subprocess module

We use the subprocess module to demonstrate a stick package issue.

# 服务端
# coding=utf-8
import socket
import subprocess

server = socket.socket()
address = ("127.0.0.1",8888)
server.bind(address)
server.listen(5)

while True:
    conn , addr = server.accept()
    while True:
        try:
            cmd = conn.recv(1024).decode("utf-8")
            print(cmd)

            if cmd == "q":
                break

            obj = subprocess.Popen(
                cmd,shell=True,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE
            )

            res = obj.stdout.read() + obj.stderr.read()
            conn.send(res)
        except Exception:
            break
    conn.close()
# 客户端
# coding=utf-8

import socket
client = socket.socket()
address = ("127.0.0.1",8888)
client.connect(address)

while True:
    cmd = input("请输入>>>")
    client.send(cmd.encode("utf-8"))

    if cmd == "q":
        break

    data = client.recv(1024)
    print(data.decode("gbk"))

client.close()

Terminal print results

请输入>>>tasklist

映像名称                       PID 会话名              会话#       内存使用 
========================= ======== ================ =========== ============
System Idle Process              0 Services                   0         24 K
System                           4 Services                   0      3,172 K
smss.exe                       352 Services                   0      1,200 K
csrss.exe                      464 Services                   0      6,656 K
wininit.exe                    572 Services                   0      5,168 K
csrss.exe                      588 Console                    1     77,948 K
services.exe                   636 Services                   0     12,288 K
lsass.exe                      652 Services                   0     11,164 K
lsm.exe                        660 Services                   0      4,664 K
winlogon.exe                   744 Console                    1      8,180 K
svchost.exe                    812 Services                   0     10,040 K
svchost.
请输入>>>dir
exe                    892 Services                   0      8,280 K
svchost.exe                    980 Services                   0     21,744 K
svchost.exe                    168 Services                   0     21,060 K
svchost.exe                    388 Services                   0     40,792 K
svchost.exe                    908 Services                   0     12,252 K
WUDFHost.exe                  1100 Services                   0      8,096 K
ZhuDongFangYu.exe             1188 Services                   0     23,784 K
svchost.exe                   1236 Services                   0     17,532 K
wlanext.exe                   1412 Services                   0      5,268 K
conhost.exe                   1420 Services                   0      2,860 K
dwm.exe                       1536 Console                    1     38,436 K
explorer.exe                  1588 Console                    1     70,028 K
spoolsv.exe                   1612 Services                   0     12,204 K
svchost.exe       

We saw after the losers tasklist command, enter other command again, or the result of the previous command,

So long proven data server for the first time sent a one-time client can not accurately received, the next data sent with the last data stick together. We received at the client when the data size of 1024 bytes is received, the server receives the execution result exceeds the size of the heap so that the result is equivalent to the back, is transmitted together, it is not the right next Run Results , then we need to solve this problem you need to use struct module

struct module

struct module ,, header must be defined first transmission header, and then transmits the real data

# 服务端
# coding=utf-8

import struct
import socket
import subprocess

server = socket.socket()
address = ("127.0.0.1",8888)
server.bind(address)
server.listen(5)

while True:
    conn,addr = server.accept()
    while True:
        try:
            cmd = conn.recv(1024).decode("utf-8")
            print(cmd)

            if cmd == "q":
                break

            obj = subprocess.Popen(
                cmd ,shell=True,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE
            )

            res = obj.stdout.read() + obj.stderr.read()
            
            # 将执行结果计算长度用i模式打包
            res_len = struct.pack("i",len(res))

            # 先发送数据长度
            conn.send(res_len)

            # 再发送真实数据
            conn.send(res)
        except Exception:
            break
    conn.close()
# 客户端
# coding=utf-8

import socket
import struct


client = socket.socket()
address = ("127.0.0.1",8888)
client.connect(address)

while True:
    cmd = input("请输入命令>>>")
    client.send(cmd.encode("utf-8"))
    if cmd == "q":
        break
    
    # 用struct模块接收的长度统一是4个字节,
    head = client.recv(4)
    # 然后用struct模块解包得到数据的真实长度,返回的是元组类型,0表示第一个元素,就是真实长度
    data_len = struct.unpack("i",head)[0]
    
    # 然后再把真实长度接收即可。
    data = client.recv(data_len)
    print(data.decode("gbk"))
client.close()

UDP protocol programming

A transmission protocol is udp

1) does not need to establish a two-way channel

2) does not stick package

3) The client sends data to the server, the server returns without waiting for the reception success

4) easy to lose data, data insecurity.

TCP: equivalent to the phone

UDP: the equivalent of texting

Easy qq chat room

# 服务端
# coding=utf-8
import socket

server = socket.socket(type=socket.SOCK_DGRAM)
address = ("127.0.0.1",8888)
server.bind(address)

while True:
    msg,addr = server.recvfrom(1024)
    print(msg.decode("utf-8"))

    # 服务端往客户端发送消息
    send_msg = input("服务端发送消息")
    server.sendto(send_msg.encode("utf-8"),addr)
# 客户端
# coding=utf-8
import socket
client = socket.socket(type=socket.SOCK_DGRAM)
address = ("127.0.0.1",8888)

while True:
    send_msg = input("请输入信息")
    client.sendto(send_msg.encode("utf-8"),address)

    data = client.recv(1024)
    print(data.decode("utf-8"))

Guess you like

Origin www.cnblogs.com/qinyujie/p/11704491.html