Socket传输简单的信息以及粘包问题的解决

  一、简单的socket程序——传输简短文字:

# -*- coding: utf-8  -*-
# -*- Author: WangHW -*-
import socket

whw_client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
whw_client.connect((‘127.0.0.1‘,9001))
while 1:
    cmd = input(‘>>>:‘).strip()
    if not cmd:
        continue
    whw_client.send(cmd.encode(‘utf-8‘))
    recv_data = whw_client.recv(1024)
    data = recv_data.decode(‘utf-8‘)
    print(‘server data:‘,data)

client

# -*- coding: utf-8  -*-
# -*- Author: WangHW -*-
import socket

whw_server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
whw_server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
whw_server.bind((‘127.0.0.1‘,9001))
whw_server.listen(5)
print(‘listening......‘)
conn,addr = whw_server.accept()
#通信循环
while 1:
    try:
        recv_data = conn.recv(1024)
        data = recv_data.decode(‘utf-8‘)
        print(‘client data:‘,data)
        conn.send(data.swapcase().encode(‘utf-8‘))
    except ConnectionResetError:
        break
conn.close()

server

  演示如下:

二、模拟SSH命令——解决粘包问题版:

  关于粘包问题的解决方案:

  在服务器端,由于解析出来的命令结果非常多,所以我们在发送结果之前需要先给客户端发送一个“报文”,这个报文保存着具体的命令结果的信息——其中关键的信息就是结果的长度,客户端只有知道这个结果的长度后,才能制定相应的接收规则:

# -*- coding: utf-8  -*-
# -*- Author: WangHW -*-
import socket
import json
import struct

whw_client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
whw_client.connect((‘127.0.0.1‘,9000))
while 1:
    try:
        cmd = input(‘>>>:‘).strip()
        if not cmd:
            continue
        #发命令
        whw_client.send(cmd.encode(‘utf-8‘))
        #1.收报头长度
        obj = whw_client.recv(10)
        #注意structunpack出来的[0]值为长度信息
        header_size = struct.unpack(‘i‘,obj)[0]
        #2.收报头——根据报头长度来收
        header_bytes = whw_client.recv(header_size)
        #3.从报头中解析出‘total_size‘
        header_json = header_bytes.decode(‘utf-8‘)
        header_dic = json.loads(header_json)
        total_size = header_dic[‘total_size‘]
        #根据total_size开始接收真实的数据
        recv_size = 0
        recv_data = b‘‘
        while recv_size < total_size:
            res = whw_client.recv(1024)
            recv_data += res
            recv_size += len(res)
        print(‘命令结果:\n‘,recv_data.decode(‘gbk‘))
    except Exception as e:
        whw_client.close()

client

# -*- coding: utf-8  -*-
# -*- Author: WangHW -*-
import socket
import subprocess
import json
import struct

whw_server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
whw_server.bind((‘127.0.0.1‘,9000))
whw_server.listen(5)
print(‘Listening......‘)
conn,addr = whw_server.accept()
while 1:
    try:
        #收命令
        cmd_recv = conn.recv(1024).decode(‘utf-8‘)
        #解析命令
        obj = subprocess.Popen(cmd_recv,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
        stdout = obj.stdout.read()
        stderr = obj.stderr.read()
        #将命令返回给客户端
        #1.制作固定报头——注意报头里面要包含数据的总长度!
        header_dic = {‘filename‘:‘whw‘,‘total_size‘:len(stdout)+len(stderr)}
        header_json = json.dumps(header_dic)
        header_bytes = header_json.encode(‘utf-8‘)
        #2.发送报头长度——struct:把数字打成固定长度
        conn.send(struct.pack(‘i‘,len(header_bytes)))
        #3.发送报头
        conn.send(header_bytes)
        #4.发送真实数据
        conn.send(stdout)
        conn.send(stderr)
    except ConnectionResetError:
        break

conn.close()

server

  演示如下:

原文地址:https://www.cnblogs.com/paulwhw/p/9092629.html

时间: 2024-07-31 23:53:26

Socket传输简单的信息以及粘包问题的解决的相关文章

DELPHI高性能大容量SOCKET并发(四):粘包、分包、解包

DELPHI高性能大容量SOCKET并发(四):粘包.分包.解包 粘包 使用TCP长连接就会引入粘包的问题,粘包是指发送方发送的若干包数据到接收方接收时粘成一包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾.粘包可能由发送方造成,也可能由接收方造成.TCP为提高传输效率,发送方往往要收集到足够多的数据后才发送一包数据,造成多个数据包的粘连.如果接收进程不及时接收数据,已收到的数据就放在系统接收缓冲区,用户进程读取数据时就可能同时读到多个数据包. 粘包一般的解决办法是制定通讯协议,由协议来规

20 Apr 18 粘包问题及解决方法

20 Apr 18 一.上节课复习 1. TCP(建立的是一个双向连接)三次握手建连接,四次挥手断连接 三次握手:    c----syn=1 seq=x--->s    s----ack=1+x syn=1 seq=y--->c    c----ack=1+y------->s    四次挥手:    s------fin=1---------->c    c------>ack=1--------->s    c------>fin=1--------->

Socket编程实践(6) --TCP粘包原因与解决

流协议与粘包 粘包的表现 Host A 发送数据给 Host B; 而Host B 接收数据的方式不确定 粘包产生的原因 说明 TCP 字节流,无边界 对等方,一次读操作,不能保证完全把消息读完 UDP 数据报,有边界 对方接受数据包的个数是不确定的 产生粘包问题的原因分析 1.SQ_SNDBUF 套接字本身有缓冲区 (发送缓冲区.接受缓冲区) 2.tcp传送的端 mss大小限制 3.链路层也有MTU大小限制,如果数据包大于>MTU要在IP层进行分片,导致消息分割. 4.tcp的流量控制和拥塞控

Socket编程实践(5) --TCP粘包问题与解决

TCP粘包问题 因为TCP协议是基于字节流且无边界的传输协议, 因此非常有可能产生粘包问题, 问题描写叙述例如以下 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvempmMjgwNDQxNTg5/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" /> 对于Host A 发送的M1与M2两个各10K的数据块, Host B 接收数据的方式不确定, 有以下

网络编程 TCP协议:三次握手,四次回收,反馈机制 socket套接字通信 粘包问题与解决方法

TCP协议:三次握手,四次挥手 TCP协议建立双向通道. 三次握手, 建连接: 1:客户端向服务端发送建立连接的请求 2:服务端返回收到请求的信息给客户端,并且发送往客户端建立连接的请求 3:客户端接收到服务端发来的请求,返回接成功给服务端,完成双向连接 第一客戶向服务端发送请求,请求建立连接 服务端同客户端的请求,并同时向客户端发送建立 连接的请求,最后客户端同意后建立 双向连接. C ----> S C <---- S - 反馈机制: 客户端往服务端发送请求,服务端必须返回响应, 告诉客户

python--subprocess,粘包现象与解决办法,缓冲区

一. subprocess 的简单用法 import subprocess sub_obj = subprocess.Popen( 'dir', #系统指令 shell=True, #固定方法 stdout=subprocess.PIPE, #标准输出 PIPE 管道,保存着指令的执行结果 stderr=subprocess.PIPE #标准错误输出 ) # dir 当前操作系统(Windows)的命令,会执行stdout print('正确输出',sub_obj.stdout.read().d

python3 tcp的粘包现象和解决办法

服务器端 import socket sk = socket.socket() sk.bind(("127.0.0.1", 6666)) sk.listen() conn, address = sk.accept() def my_send(msg): bs = msg.encode("utf-8") len_str = format(len(bs), "04d") # 定长4位 conn.send(len_str.encode("ut

Python TCP Socket 传输服务器资源信息(C/S)

服务器端脚本: 1 #!/usr/bin/env python 2 # coding:utf8 3 from socket import * 4 import os 5 import time 6 HOST='' 7 PORT=21567 8 BUFSIZ=1024 9 ADDR=(HOST,PORT) 10 11 tcpSerSock = socket(AF_INET,SOCK_STREAM) 12 tcpSerSock.bind(ADDR) #创建套接字 13 tcpSerSock.list

Socket编程--TCP粘包问题

TCP是个流协议,它存在粘包问题 产生粘包的原因是: TCP所传输的报文段有MSS的限制,如果套接字缓冲区的大小大于MSS,也会导致消息的分割发送. 由于链路层最大发送单元MTU,在IP层会进行数据的分片. 应用层调用write方法,将应用层的缓冲区中的数据拷贝到套接字的发送缓冲区.而发送缓冲区有一个SO_SNDBUF的限制,如果应用层的缓冲区数据大小大于套接字发送缓冲区的大小,则数据需要进行多次的发送. 粘包问题的解决 ①:发送定长包 这里需要封装两个函数: ssize_t readn(int