本节内容

1、概述

2、socket接收大数据

3、中文字符的坑

一、概述

  上篇博客写到了,就是说当服务器发送至客户端的数据,大于客户端设置的数据,则就会把数据服务端发过来的数据剩余数据存在IO缓冲区中,那我们如何解决这个问题呢?

  有的同学就说了:

  1. 改大客户端接收的数据的大小=>这个方案并不能解决问题,因为官方建议最多只能接收8k的数据,那服务端发送过来的数据大于8K咋办,很显然不行
  2. 客户端可以多收几次=>客户端需要收多少次,才能把这个命令返回的结果全部收回来呢?并且怎么确定这条命令返回的结果已经被全部收回来了呢?

  很明显,上面第二种思路靠谱一点:就是说服务端给客户端发数据之前,先计算一下给客户端要发多少数据,我先判断 len 一下,就 ok 了,先让客户端知道服务端发送过来的大小,比如说发过来的是5k大小,客户端接收到了这个5k大小以后,就知道需要接收多少次了,循环接收,直到5k数据全部接收完毕为止。

二、socket接收大数据

2.1、逻辑图

2.2、逻辑代码

1、客户端代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import socket
 
client = socket.socket()
client.connect(("localhost",9999))
 
while True:
    cmd = input(">>>:").strip()
    if len(cmd) == 0:continue
    client.send(cmd.encode("utf-8"))
    cmd_res_size = client.recv(1024)  #接收命令的长度
    print("命令结果大小:",cmd_res_size.decode())
    recevied_size  = 0   #接收客户端发来数据的计算器
    recevied_data = b''  #客户端每次发来内容的计数器
    while recevied_size < int(cmd_res_size.decode()):  #当接收的数据大小 小于 客户端发来的数据
        cmd_res = client.recv(1024)
        recevied_size += len(cmd_res)  #每次收到的服务端的数据有可能小于1024,所以必须用len判断
        recevied_data += cmd_res
    else:
        print(recevied_data.decode("utf-8","ignore"))
        print("cmd res receive done ....",recevied_size)
 
client.close()

2、服务端代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import socket,os
 
server = socket.socket()
server.bind(("localhost",9999))
server.listen(5)
while True:
    conn,addr = server.accept()
    print("new addr:",addr)
    while True:
        data = conn.recv(1024)
        if not data:
            print("客户端已断开")
            break
        print("执行指令:",data)
        cmd_res = os.popen(data.decode()).read()
        print("before send:",len(cmd_res))
        if len(cmd_res) == 0:
            cmd_res = "cmd has no output...."
        conn.send( str(len(cmd_res.encode())).encode() )  #发送服务端发送给客户端数据的长度
        conn.send(cmd_res.encode("utf-8"))   #发送服务端的数据
        print("send done")
server.close()

上面的代码解决了上面博客,客户端接收大数据出现的疑难杂症,问题表现,请查看:猛击这里 中的 socket接收大数据困惑。

三、中文字符的坑

3.1、客户端接收数据大小和实际大小不一致

说明:客户端在接收数据的大小会和实际数据带下不一样,感觉实际数据要比客户端接收的数据要大,这是为什么呢?我们先来看一下现象吧。

1、客户端代码改动如图:

2、服务端代码改动如图:

3、实现的效果图:

上面的两个数据应该一样的呀,为啥不一样呢?为啥之前的就能一样呢?

答:因为python用计算中文字符,按字符和字节算的话,长度的值是不一样的,一个  中文字符=3个字节  ,如图:

网络编程基础【day09】:socket接收大数据(五)的更多相关文章

  1. 【python】-- Socket接收大数据

    Socket接收大数据 上一篇博客中的简单ssh实例,就是说当服务器发送至客户端的数据,大于客户端设置的数据,则就会把数据服务端发过来的数据剩余数据存在IO缓冲区中,这样就会造成我们想要获取数据的完整 ...

  2. 从零开始学Python第八周:网络编程基础(socket)

    Socket网络编程 一,Socket编程 (1)Socket方法介绍 Socket是网络编程的一个抽象概念.通常我们用一个Socket表示"打开了一个网络链接",而打开一个Soc ...

  3. 网络编程 - socket接收大数据

    通过socket,实现客户端发送命令,将服务端执行出的结果,反回到客户端,主要4个步骤:1.服务端返回数据: 2.服务端返回数据的大小: 3.客户端接收返回数据的大小: 4.客户端按返回数据大小接收数 ...

  4. 第1章 网络编程基础(2)——Socket编程原理

    Socket编程原理 Socket是网络通信端点的一种抽象,它提供了一种发送和接收数据的机制. 流socket(SOCK_STREAM):双向.有序.无重复.并且无记录边界 数据报Socket(SOC ...

  5. 网络编程基础之Socket套接字

    一.Socket介绍 1.什么是socket? Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口.在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族 ...

  6. python网络编程基础之socket粘包现象

    粘包现象两种 登陆 #服务端import json import socket server=socket.socket()#创建socket对象 ip_port=('127.0.0.1',8001) ...

  7. 网络编程基础之Socket套接字简单应用

    一.Socket套接字实现通信循环 所谓通信循环,简单理解就是客户端可以给服务端循环发送信息并获得反馈的过程. 1.基础版 通信循环的程序分为两部分,即两个python模块,分别为客户端.py和服务端 ...

  8. 网络编程基础之socket套接字编程实现同一IP下的信息传输

    鲁照山 1.网络协议的5层模型,每层内容的整理 2.画图描述三次握手四次挥手,和C端S端的状态 3.写一个客户端,实现给服务端发送hello world 字符串, 写一个服务端,将客户端发送的数据变成 ...

  9. 网络编程 基础 基于socket的tcp和udp连接

    网络开发的框架 C/S B/S 架构 程序都是bs架构的程序(b指浏览器,s指服务器) c(client)是客户端,s(server)是服务器 bs架构是cs架构的一种 未来的趋势, pc端bs架构, ...

随机推荐

  1. Codeforces Round #424 Div. 1

    A:二分答案,从左往右考虑每个人,选尽量靠左的钥匙即可. #include<iostream> #include<cstdio> #include<cmath> # ...

  2. Hat’s Words HDU - 1247 字典树

    题意:给出数个单词 输出单词 如果该单词 是由字典中的单词组成的 思路:字典树 先把全部建树  然后对于每一个单词进行分割,分别拿两半到字典树里面去找 小心RE! #include<bits/s ...

  3. bzoj 2038: [2009国家集训队]小Z的袜子(hose) (莫队)

    Description 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命……具体来说,小Z把这N只袜 ...

  4. IDEA中Maven项目使用Junit4单元测试的写法

    IDEA默认是安装了junit控件的,直接使用就好了 在maven项目的pom.xml文件中添加依赖 <dependency> <groupId>junit</group ...

  5. npm 常规错误

    Unexpected end of JSON input while parsing near 意外结束.JSON解析期间 解决办法: npm cache clean --force 解释:Force ...

  6. 【C++】VS2015/VS2017连接Mysql数据库教程

    要给C++程序连接MySQL数据库,分别需要: 安装MySQL Server 下载MySQL Connector/C++ 在IDE中配置依赖 然后就可以在代码中调用API,来连接以及操作数据库. 一. ...

  7. BZOJ 2728: [HNOI2012]与非(位运算)

    题意 定义 NAND(与非)运算,其运算结果为真当且仅当两个输入的布尔值不全为真,也就是 A NAND B = NOT(A AND B) ,运算位数不会超过 \(k\) 位, 给你 \(n\) 个整数 ...

  8. 洛谷 P1272 重建道路 解题报告

    P1272 重建道路 题目描述 一场可怕的地震后,人们用\(N\)个牲口棚\((1≤N≤150\),编号\(1..N\))重建了农夫\(John\)的牧场.由于人们没有时间建设多余的道路,所以现在从一 ...

  9. luogu4162 最长距离 (dijkstra)

    相邻格子连双向边,如果一个点有障碍,那进它的边权就是1,否则是0 这样的话,两点间的最短路+[起始点有障碍],就是从一个点走到另一个需要清除的障碍的个数 求出最短路后枚举这两个点就可以了 然而30*3 ...

  10. poj3259Wormholes (Bellman_Ford/SPFA/Floyed算法判断是否存在负环)

    题目链接:http://poj.org/problem?id=3259 题目大意:一个图,有n个顶点,其中有m条边是双向的且权值为为正,w条边是单向的且权值为负,判断途中是否存在负环,如果有输出YES ...