TCP协议下大数据传输IOCP乱序问题
毕业后稀里糊涂的闭门造车了两年,自己的独立博客也写了两年,各种乱七八糟,最近准备把自己博客废了,现在来看了下这两年写的对我来说略微有点意义的文章只此一篇,转载过来以作留念。
写的很肤浅且凌乱,请见谅。
我的服务器主要完成一个内网音视频实时转发功能,以及其他一些业务。设计大概如下:
服务器上分为接收线程,业务处理线程,发送线程。接收线程socket绑定到完成端口。业务处理线程是采用多线程的模拟完成端口,发送线程也是多线程采用模拟完成端口。这样做的目的是想业务处理线程阻塞并不影响发送和接收。
客户端业务层需要发送一个数据,我视为大包数据,传输层把大包数据进行拆分,变成小包发送到服务器。服务器收齐一个大包后,加入接收队列。业务处理线程从接收队列获取大包数据,抛给业务层。服务器业务层处理后把需要转发的数据放到发送队列。发送线程从发送队列取出数据转发给需要接收数据的客户端。
此时接收客户端收到乱序,起初我怀疑是多线程传输导致的乱序。认为采用了异步传输,又多条线程发送,那么可能有的包先到有的包后到。但是!采用的TCP传输协议理论上是不会乱序的。
一、排除SEND,WSASEND导致乱序的问题
要知道如果采用的是send,TCP协议下,只要我们保证调用send是有序的,那么数据拷贝到send缓冲就是有序的,TCP协议会保证数据的顺序性到达。即便是WSASend,采用TCP原理都一样,只是WSA是非阻塞等待,它也会保证按顺序拷贝进socket的send缓冲区。所以WSASend基于TCP协议就是顺序到达的。所以,如果你的程序设计上是以小包发送为单位,发生了乱序,那一定是你设计的问题。
二、检查服务器接收数据是否乱序
这个看个人项目怎么设计了,我这里打日志是已经排除了服务器接收数据乱序的可能。
三、排除多线程发送导致的乱序
每条线发送线程从发送队列取大包数据,如果发送队列本身是顺序的,那么取出来发送这个过程就应该是顺序的。如果队列里存的是一次send能允许的最大小包,那么也应该是顺序到达(结合问题一来思考)。
四、那我的问题在哪里
答案还是多线程发送,以及多条业务处理线程。刚刚问题三虽然我否定了多线程发送导致的乱序,但是请仔细看我说的前提,是以小包为单位。
在我这个程序里,设定的是以大包为单位,大包是由小包组成的,IOCP完成端口能监控到IO完成情况,也就是小包的完成情况,但是并不能监控大包完成情况。我的各种设定只是保证了取大包这一刻是有序的。如果大包ID=1是由100个小包组成,大包ID=2是由1个小包组成,在实际发送的时候就会出现:
线程1 获取大包ID=1
线程2获取大包ID=2
线程1 发送ID=1的第一个小包
线程1 发送ID=1的第二个小包
…….线程1 发送ID=1的第n个小包
线程2发送ID=2的第1个小包
…..线程1 发送ID=1的第m个小包
客户端就先收集齐了大包ID=2的所有小包,反馈给业务层或者加入接收队列,所以业务层或者接收队列看到的数据就是乱序的。
除了发送线程,业务处理线程也是多线程,业务处理线程会把处理后的数据add到发送队列,这个add过程本身就不能保证是有序的。也就是说在send前,数据其实已经可能存在乱序了。
五、小结
如果要严格来说,TCP下IOCP本身不是导致乱序的原因,WSASend只要顺序调用也不存在乱序一说,真正导致乱序的是自己设计的问题。
题外话:
回顾这两年自己闭门造车的过程,各种尝试与猜测,哈,终究只是在浪费时间。大学一直在搞asp.net,实习搞java和android,毕业了却在做c++,哈,各种折腾到现在没有一项觉得做的深入的。从0基础开始搞c++从0开始搞传输,走了很多弯路进了很多坑,人又笨,掉进去了半天都怕不上来。。
最后这个服务器转发的传输协议坑了6个大的版本后,在第7个版本,终于经过测试能跑满千兆带宽,6核12线程的cpu消耗5%左右。不得不吐槽一下IOCP真的很厉害。
TCP协议下大数据传输IOCP乱序问题的更多相关文章
- tcp协议下的Socket
import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net ...
- TCP协议传输大文件读取时候的问题
TCP协议传输大文件读取时候的问题 大文件传不完的bug 我们在定义的时候定义服务端每次文件读取大小为10240, 客户端每次接受大小为10240 我们想当然的认为客户端每次读取大小就是10240而把 ...
- TCP协议下的服务端并发,GIL全局解释器锁,死锁,信号量,event事件,线程q
TCP协议下的服务端并发,GIL全局解释器锁,死锁,信号量,event事件,线程q 一.TCP协议下的服务端并发 ''' 将不同的功能尽量拆分成不同的函数,拆分出来的功能可以被多个地方使用 TCP服务 ...
- TCP协议下Socket的基础编程类型
套接字的基本操作有: 创建(socket).命名(bind).侦听(listen).连接(accept).关闭(shutdown).发送(send).接受(recv). 下面逐个分析: 一.创建(so ...
- 基于tcp协议下粘包现象和解决方案,socketserver
一.缓冲区 每个 socket 被创建后,都会分配两个缓冲区,输入缓冲区和输出缓冲区.write()/send() 并不立即向网络中传输数据,而是先将数据写入缓冲区中,再由TCP协议将数据从缓冲区发送 ...
- 《java入门第一季》之tcp协议下的网络编程
tcp协议相对于udp更加安全. 首先看一下需求:服务器端开启,多个客户端同时向服务器发送数据,看哪个客户端先到达. 说明:这里我开启三个电脑实验,一台电脑写服务器端的程序,两台电脑开客户端的程序.服 ...
- 在TCP协议下的数据传送
本人小白菜逼一枚,,,,刚建立博客,也写不了太深入的,就写点上课的笔记什么的.有错误希望广大博友指出,我一定虚心学习接收改正. 我的新浪邮箱:liudaohui0805@sina.com 我的QQ邮箱 ...
- tcp协议下粘包问题的产生及解决方案
1 tcp有粘包及udp无粘包 - TCP 是面向连接的,面向流的可靠协议:发送端为了将多个发往接收端的包,更有效的发到对方,使用了优化方法(Nagle算法),将多次间隔较小且数据量小的数据, 合并成 ...
- 基于TCP协议的大文件传输(粘包问题处理)
基于TCP的大文件上传服务端实现 # 服务端 # -*- coding: utf-8 -*- from socket import * import json, struct server = soc ...
随机推荐
- [Leetcode|SQL] Combine Two Tables
Table: Person +-------------+---------+ | Column Name | Type | +-------------+---------+ | PersonId ...
- [Leetcode] Scramble String
Given a string s1, we may represent it as a binary tree by partitioning it to two non-empty substrin ...
- 51nod算法马拉松13
A 取余最长路 不难发现路径可以拆成三条线段,只要知道两个转折点的位置就能计算出答案. 设sum(i,l,r)表示第i行从l到r元素的和,则答案可以表示为sum(1,1,x)+sum(2,x,y)+s ...
- App所需申请资料
准备资料 企业五证 营业执照 税务登记证 组织机构代码证 银行开户许可证 法人身份证 新邮箱 申请一个新的邮箱地址,供申请以下材料使用 苹果证书申请 AppleID 申请邓氏编码需要有AppleID ...
- 如何在weka中连接数据库(转)
相关准备: Weka.mysql已安装 MYSQL Driver for JDBC 1.进入weka的安装目录 1)新建文件夹lib和文件夹weka,然后将mysql-connector-java-5 ...
- Mobile data
1.Consume REST web services from app 2.De-serialize JSON into an in-memory object collection 3.Save ...
- js通过sessionStorage实现的返回上一页
通常,我们都会使用比较熟悉的javascript:history.go(-1)来实现返回上一页,此种方法有一个问题就是返回上一页后不能刷新当前页面,给我们的开发带来了一定的不便,显然有时这种方法就不是 ...
- redis集群搭建
1. Redis Cluster的架构图. (1)所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽. (2)节点的fail是通过集群 ...
- 2016HUAS暑假集训训练题 G - Oil Deposits
Description The GeoSurvComp geologic survey company is responsible for detecting underground oil dep ...
- readyState0 1 2 3 4..
0:请求未初始化(还没有调用 open()). 1:请求已经建立,但是还没有发送(还没有调用 send()). 2:请求已发送,正在处理中(通常现在可以从响应中获取内容头). 3:请求在处理中:通常响 ...