1,socket(套接字)

    socket层

        

        Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口

      server端

        import socket
        sk = socket.socket()
        sk.bind(('127.0.0.1',8898))  #把地址绑定到套接字
        sk.listen()          #监听链接
        conn,addr = sk.accept() #接受客户端链接
        ret = conn.recv(1024)  #接收客户端信息
        print(ret)       #打印客户端信息
        conn.send(b'hi')        #向客户端发送信息
        conn.close()       #关闭客户端套接字
        sk.close()        #关闭服务器套接字           根据情况选择

      client 端

        import socket
        sk = socket.socket()           # 创建客户套接字
        sk.connect(('127.0.0.1',8898))    # 尝试连接服务器
        sk.send(b'hello!')
        ret = sk.recv(1024)         # 对话(发送/接收)
        print(ret)
        sk.close()            # 关闭客户套接字

2,粘包

    1,什么是粘包        例如基于tcp的套接字客户端往服务端上传文件,        发送时文件内容是按照一段一段的字节流发送的,        在接收方看了,根本不知道该文件的字节流从何处开始,在何处结束    2,粘包是怎么造成的        发送方引起的粘包是由TCP协议本身造成的,TCP为提高传输效率,        发送方往往要收集到足够多的数据后才发送一个TCP段。        若连续几次需要send的数据都很少,通常TCP会根据优化算法把这些数据合成一个TCP段后一次发送出去,        这样接收方就收到了粘包数据。    3,tcp传输的原理            用TCP协议发送时,由于TCP是数据流协议,因此不存在包大小的限制(暂不考虑缓冲区的大小),            这是指在用send函数时,数据长度参数不受限制。            而实际上,所指定的这段数据并不一定会一次性发送出去,      TCP特点:         会将数据量比较小的并且时间间隔比较短的数据         一次性打包发送给对方

    4,发生黏包的两种情况:        情况一 发送方的缓存机制            发送端需要等缓冲区满才发送出去,造成粘包(发送数据时间间隔很短,数据了很小,会合到一起,产生粘包)        情况二 接收方的缓存机制            接收方不及时接收缓冲区的包,造成多个包接收(客户端发送了一段数据,服务端只收了一小部分,                服务端下次再收的时候还是从缓冲区拿上次遗留的数据,产生粘包)

        ps:主要还是因为接收方不知道消息之间的界限,不知道一次性提取多少字节的数据所造成的    *****************

    
  解决方案:    struct 模块    服务端       1.先制作一个发送给客户端的字典        2.制作字典的报头        3.发送字典的报头        4.发送字典        5.再发真实数据

    客户端        1.先接受字典的报头        2.解析拿到字典的数据长度        3.接受字典        4.从字典中获取真实数据的长度        5.接受真实数据    把报头做成字典,字典里包含将要发送的真实数据的详细信息,然后json序列化,然后用struck将序列化后的数据长度打包成4个字节      
发送时 接收时

先发报头长度

先收报头长度,用struct取出来
再编码报头内容然后发送 根据取出的长度收取报头内容,然后解码,反序列化
最后发真实内容 从反序列化的结果中取出待取数据的详细信息,然后去取真实的数据内容

    客户端

                  import socket                  import struct                  import json                  print("客户端")

                  client = socket.socket()

                  # 绑定服务器ip和端口                  client.connect(('127.0.0.1', 8333))                  # 循环收发数据                  while True:                      msg = input('>>>>>:').encode('utf-8')                      # 为了防止出现你等我,我等你这种情况,(客户端按了end,服务端没接受到数据                      #  而客户端此时也走到了recv阶段,服务端一直处于recv阶段,所以一直处于阻塞状态                      if len(msg) == 0:continue   # 所以要有这个判断,continue结束本次循环                      client.send(msg)                      # 先接受报头长度                      header_dict = client.recv(4)                      # 解析报头,获取字典的长度                      dict_size = struct.unpack('i', header_dict)[0]                      dict_bytes = client.recv(dict_size)                      dict_json = json.loads(dict_bytes.decode('utf-8'))                      print(dict_json)                      recv_size = 0                      real_data = b''                      while recv_size < dict_json.get('file_size'):                          data = client.recv(1024)                          real_data += data                          recv_size += len(data)                      print(real_data.decode('gbk'))                      client.close()       服务端:                                          import socket                  import subprocess                  import struct                  import json

                  server = socket.socket()                  server.bind(('127.0.0.1',8080))                  server.listen(5)

                  while True:                      conn, addr = server.accept()                      while True:                          try:                              cmd = conn.recv(1024)                              if len(cmd) == 0:break                              cmd = cmd.decode('utf-8')                              obj = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)                              res = obj.stdout.read() + obj.stderr.read()                              d = {'name':'jason','file_size':len(res),'info':'asdhjkshasdad'}                              json_d = json.dumps(d)                              # 1.先制作一个字典的报头                              header = struct.pack('i',len(json_d))                              # 2.发送字典报头                              conn.send(header)                              # 3.发送字典                              conn.send(json_d.encode('utf-8'))                              # 4.再发真实数据                              conn.send(res)                              # conn.send(obj.stdout.read())                              # conn.send(obj.stderr.read())                          except ConnectionResetError:                              break                      conn.close()
  

转载于:https://www.cnblogs.com/Fzhiyuan/p/11318405.html

socket,与粘包相关推荐

  1. python串口数据分包_python TCP Socket的粘包和分包的处理详解

    概述 在进行TCP Socket开发时,都需要处理数据包粘包和分包的情况.本文详细讲解解决该问题的步骤.使用的语言是Python.实际上解决该问题很简单,在应用层下,定义一个协议:消息头部+消息长度+ ...

  2. 详述 Java NIO 以及 Socket 处理粘包和断包方法

    文章目录 Java NIO 通道 缓冲区 代码示例 第一部分 第二部分 选择器 Socket 处理粘包 & 断包问题 第一个问题:对于粘包问题的解决 第二个问题:对于断包问题的解决 示例代码 ...

  3. c# socket 解决粘包,半包

    处理原理: 半包:即一条消息底层分几次发送,先有个头包读取整条消息的长度,当不满足长度时,将消息临时缓存起来,直到满足长度再解码 粘包:两条完整/不完整消息粘在一起,一般是解码完上一条消息,然后再判断 ...

  4. socket Php 粘包,python3 tcp的粘包现象和解决办法解析

    这篇文章主要介绍了python3 tcp的粘包现象和解决办法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 服务器端 import socket ...

  5. Socket解决粘包问题2

    在AsynServer中对接收函数增加接收判断,如果收到客户端发送的请求信息,则发送10个测试包给发送端,否则继续接收,修改后的接收代码如下: private void AsynReceive(){b ...

  6. java socket分包粘包 代码_分享java中处理socket通信过程中粘包情况的实例代码

    本篇文章主要介绍了java中处理socket通信过程中粘包的情况,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 这两天学习了java中处理socket通信过程中粘包的情况,而且很重要,所以,今天添 ...

  7. C# Socket的粘包处理(转)

    http://www.cnblogs.com/aarond/p/Socket111.html 当socket接收到数据后,会根据buffer的大小一点一点的接收数据,比如: 对方发来了1M的数据量过来 ...

  8. socket的长连接、短连接、半包、粘包与分包

    socket的半包,粘包与分包的问题和处理代码:http://blog.csdn.net/qq_16112417/article/details/50392463 知乎关于长连接和短连接:https: ...

  9. TCP通信粘包问题分析和解决

    在socket网络程序中,TCP和UDP分别是面向连接和非面向连接的.因此TCP的socket编程,收发两端(客户端和服务器端)都要有成对的socket,因此,发送端为了将多个发往接收端的包,更有效的 ...

  10. 学习笔记(12):Python网络编程并发编程-解决粘包问题-简单版本

    立即学习:https://edu.csdn.net/course/play/24458/296243?utm_source=blogtoedu 粘包现象的解决:简单版 1.思路:       在服务器 ...

最新文章

  1. linux ps(process status) 命令详解
  2. c语言微信昵称大全女生优雅经典的,微信昵称大全女生优雅_有深度有内涵的昵称...
  3. 在Linux执行命令报错”Arg list too long”的原因分析
  4. 开发Eclipse插件
  5. 飞畅科技-工业交换机防雷知识总结
  6. cmstop中实例化controller_admin_content类传递$this,其构造方法中接收到的是--名为cmstop的参数--包含cmstop中所有属性...
  7. 自营型电商和平台型电商的行业秘密是什么?
  8. 数据科学家访谈录 百度网盘_您应该在数据科学访谈中向THEM提问。
  9. ICMP报文分析(转)
  10. mysql char(36)_MySQL中char(36)被认为是GUID导致的BUG及解决方案
  11. 二叉树——淘汰赛(洛谷 P4715)
  12. asp.net处理get,post数据
  13. 《Spring技术内幕》学习笔记17——Spring HTTP调用器实现远程调用
  14. 黑马程序员-面向对象-08天-2 (多态)
  15. HTML其他常用标签
  16. dreamweaver php代码提示框,PHP 5.4中的Dreamweaver CS5代码提示和语法错误
  17. vf计算机教程,VF教程,打印版.pdf
  18. 质量评估指标:PSNR(Peak signal-to-noise ratio 峰值信噪比)
  19. 【SpringBoot深入浅出系列】SpringBoot之集成JUnit5进行单元测试
  20. html都有哪些事件,HTML有哪些事件属性?

热门文章

  1. 一个mysql复制中断的案例
  2. 星级评价组件--引发对React组件的思考
  3. php之isset() 、empty()、is_null()的区别
  4. 网站调用百度地图 根据地址查询经纬度
  5. Python深入06 Python的内存管理
  6. Linux操作系统的8个经典技巧
  7. javascript:URL编解码和父子窗口交互
  8. [转贴]基于HTTP的QQ协议
  9. 叮叮叮 重点之中的python必备英语单词(2)来啦!请记得查收
  10. web前端之css快速入门