一、简单的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

  演示如下:

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

  1. 网络编程——TCP协议、UDP协议、socket套接字、粘包问题以及解决方法

    网络编程--TCP协议.UDP协议.socket套接字.粘包问题以及解决方法 TCP协议(流式协议) ​ 当应用程序想通过TCP协议实现远程通信时,彼此之间必须先建立双向通信通道,基于该双向通道实现数 ...

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

    粘包 使用TCP长连接就会引入粘包的问题,粘包是指发送方发送的若干包数据到接收方接收时粘成一包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾.粘包可能由发送方造成,也可能由接收方造成.TCP为提 ...

  3. C#高性能大容量SOCKET并发(五):粘包、分包、解包

    原文:C#高性能大容量SOCKET并发(五):粘包.分包.解包 粘包 使用TCP长连接就会引入粘包的问题,粘包是指发送方发送的若干包数据到接收方接收时粘成一包,从接收缓冲区看,后一包数据的头紧接着前一 ...

  4. 什么是TCP粘包?怎么解决这个问题

    在socket网络编程中,都是端到端通信,由客户端端口+服务端端口+客户端IP+服务端IP+传输协议组成的五元组可以明确的标识一条连接.在TCP的socket编程中,发送端和接收端都有成对的socke ...

  5. 网络编程----粘包以及粘包问题的解决、FTP上传

    一.粘包现象 让我们基于tcp先制作一个远程执行命令的程序(1:执行错误命令 2:执行ls 3:执行ifconfig) 注意注意: res=subprocess.Popen(cmd.decode('u ...

  6. python 粘包问题及解决方法

    一粘包 TCP协议是面向对象的,面向流的,提高可靠性服务.使用了优化算法,Nagle算法.将多次间隔较少且数据量小的数据,合并成一个大的数据块,然后进行封包.这样接收端就很难分辨出来.TCP协议数据是 ...

  7. socket粘包现象加解决办法

    socket粘包现象分析与解决方案 简单远程执行命令程序开发(内容回顾) res = subprocess.Popen(cmd.decode('utf-8'),shell=True,stderr=su ...

  8. Socket编程(4)TCP粘包问题及解决方案

    ① TCP是个流协议,它存在粘包问题 TCP是一个基于字节流的传输服务,"流"意味着TCP所传输的数据是没有边界的.这不同于UDP提供基于消息的传输服务,其传输的数据是有边界的.T ...

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

    TCP协议:传输协议,基于端口工作 三次握手,四次挥手 TCP协议建立双向通道. 三次握手, 建连接: 1:客户端向服务端发送建立连接的请求 2:服务端返回收到请求的信息给客户端,并且发送往客户端建立 ...

随机推荐

  1. Liunx----vi编辑器

    关于vi编辑器基本的用法总结如下: vi是linux下的一款文编编辑器. 进入vi的方法:在系统启动起来后,直接键入vi或vi 文件名: 进去后输入内容方法:输入a或i,切换到编辑模式: 退出编辑模式 ...

  2. LeetCode - Rectangle Overlap

    A rectangle is represented as a list [x1, y1, x2, y2], where (x1, y1) are the coordinates of its bot ...

  3. 【BZOJ1930】【SHOI2003】吃豆豆

    初见杀…… 原题: 两个PACMAN吃豆豆.一开始的时候,PACMAN都在坐标原点的左下方,豆豆都在右上方.PACMAN走到豆豆处就会吃掉它.PACMAN行走的路线很奇怪,只能向右走或者向上走,他们行 ...

  4. linux 文件管理操作入门

    mkdir -p /root/kali/bp/shell  一路创建文件夹直到生成文件夹shell,中间没有kali文件夹的话也会自动创建生成 tar解压缩 范例一:将整个 /etc 目录下的文件全部 ...

  5. MySQL Binlog和Relaylog生成和清理

    =====================================================================================binlog文件生成:在每条二 ...

  6. openresty 集成lua-resty-mail +smtp2http 扩展灵活的mail 服务

    lua-resty-mail 是一个不错的openresty mail 扩展,我们可以用来进行邮件发送,支持附件功能 smtp2http 是一个smtp 服务,可以将smtp 请求数据转换为http ...

  7. Unity3D\2D手机游戏开发 学习

    using UnityEngine; using System.Collections; [AddComponentMenu("Game/AutoDestroy")] public ...

  8. Space Shooter 学习

    using UnityEngine; using System.Collections; /// <summary> /// 背景滚动 /// </summary> publi ...

  9. phpstorm 2017激活码(方法)

    JetBrains激活 JetBrains 授权服务器(License Server URL):http://idea.imsxm.com 使用方法:激活时选择License server 填入htt ...

  10. 将数据挂载到 docker 容器中的3种方式:volume、bind mount、tmpfs

    出处:https://deepzz.com/post/the-docker-volumes-basic.html