谁能说一下解决思路,可以参考一下QQ的文件传输。。
直连太慢的话,找个双方都快的跳板,无需完全传到跳板上再传出。
非常赞同马瑜的使用UDP传送文件的方法。要想传送快,且文件不太大,使用UDP。不过要自己控制组包、包确认、重传机制。要想速度更快,建议使用驱动发原始以太包,Windows下使用NDIS协议层驱动(NDIS分为协议层、中间层、小端口驱动)。我做过一个给公安用的警用木马穿墙的通信机制,就使用NDIS协议层驱动发包,经过测试可以稳定发送100MB的文件到美国的机器上,且错误率非常小。但要控制好组包、包确认、重传机制,且经过严格的测试,确定相关参数。现提供一下当时的设计方法:
1.收包算法:发包方每发送一个文件产生随机生成的一个链路号并携带在数据中。接收方使用HashTableA实现接收的数据包按链路号插入,并使用拉链法把收到的包按包序插入到桶内,形成一个链表,表头挂在桶内。HashTableA的Key为链路号,Data为按序号排列的数据包链表。见下图:
插入包时因为要遍历链表找到对应包的序号插入,所以当后面的包到来时,自然知道前面差哪个包。此时记录缺少的包到list<int> listLackPackets中。当缺少的包到来时,从list<int>中删除。当最后一个包到来时置BOOL bLastPacket为TRUE,判断若listLackPackets中为空,则摘除此链路的所有数据包并保存为文件。每条链路设置一个超时,记录此链路最后一次收到包的时间,若int nLastAcceptTime>=MAX_TIME_OUT还没收到包则删除此链路的所有数据包。以上信息保存按链路号保存在HashTableB中。如下图:
使用一条叫做DispatchThread的线程去轮询HashTableB中的每个链路的包描述符,判断此次通信是否包全部收完,若收完则把此链路号对应于HashTableA中的数据保存在硬盘。
重传机制:间谍软件的重传机制建立在原收包算法基础上,分为丢包重传和差错重传。数据包中结构体中的包类型为0x03。接收端:丢包重传:接收端在接收包后往HashTable中的拉链(链表)插入包时可以知道前面还没接收到的包序号,此时记录这些没收到的包“应该到达的时间”到list结构。“应该到达的时间” 为后面的包到达时间。一旦“应该到达的时间”设置,后面的包到达后不再设置。在分发线程(即判断一个链路的包收完整就写入磁盘的线程)中,轮询检测每个包是否超时未到达,未到达则发送数据包到对方要求重发。检测包超时方法为如果“当前时间”减去“应该到达的时间”大于等于MAX_TIMEOUT(自己设定的一个值)则为超时,设置此MAX_TIMEOUT时间间隔是考虑到路由选择、拥塞等会影响包到达时间。要求重发后,置“应该到达的时间”+=MAX_REACH(在后面的迭代中会逐步完善MAX_TIMEOUT和MAX_REACH 值)。
差错重传:在收到包后即刻计算数据的checksum与发送过来的描述结构体中的checksum字段对比,若不相等则要求重发。置“应该到达的时间” +=MAX_REACH。
发送端:发送端使用队列保存发送文件、重发时发送的数据包,先发送的数据包在队首。队列保存足够发送端收到接收端要求重发数据时间差的数据,最少缓存2000个数据包。 当队列满时一次性从队首删除MAX_DELETE个数据包。发送端收到接收端要求重发数据时,依据包中的链路号和包序去队列中查找并发送数据包到对方。发送端重发时的数据包也保存到队列,当接收端收到发送端重发的数据包时经计算有差错或没收到此数据包时,可以重新请求发送端发送此数据包。起先考虑用队列加两层Hash表的方法加快发送端处理要求重传数据包的查询速度。但从队列一次性删除MAX_DELETE个数据包时,也需大量的查找,费时间,且要求重传的几率并不高,反而损失性能,所以舍去此种方法。
以下几点是我个人的理解:1.文件需要按块传输,并且块的大小需要根据网络环境、MTU,包的丢失率几个方面来动态计算控制2.需要对传输间隔时间进行控制,可以根据网络状态(丢包率为依据)来动态调整传输间隔,好的状态下尽可能缩短,直到丢包率出现。3.最后一点是建议,如果保证可以有效控制UDP的传输节奏、丢包率、重传率,最好采用UDP,效率上要优于TCP。一是UDP较TCP少了三次握手时间,连接上要优于TCP,二是TCP按顺序传输,并且接受方需要进行校验和确认,过于严格的传输过程,导致灵活性差了些。当然,TCP也有适用的情况,这个要看具体应用了。
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
暂无简介
文章 0 评论 0
接受
发布评论
评论(3)
直连太慢的话,找个双方都快的跳板,无需完全传到跳板上再传出。
非常赞同马瑜的使用UDP传送文件的方法。要想传送快,且文件不太大,使用UDP。不过要自己控制组包、包确认、重传机制。
要想速度更快,建议使用驱动发原始以太包,Windows下使用NDIS协议层驱动(NDIS分为协议层、中间层、小端口驱动)。
我做过一个给公安用的警用木马穿墙的通信机制,就使用NDIS协议层驱动发包,经过测试可以稳定发送100MB的文件到美国的机器上,且错误率非常小。
但要控制好组包、包确认、重传机制,且经过严格的测试,确定相关参数。
现提供一下当时的设计方法:
1.收包算法:
发包方每发送一个文件产生随机生成的一个链路号并携带在数据中。接收方使用HashTableA实现接收的数据包按链路号插入,并使用拉链法把收到的包按包序插入到桶内,形成一个链表,表头挂在桶内。HashTableA的Key为链路号,Data为按序号排列的数据包链表。见下图:
插入包时因为要遍历链表找到对应包的序号插入,所以当后面的包到来时,自然知道前面差哪个包。此时记录缺少的包到list<int> listLackPackets中。当缺少的包到来时,从list<int>中删除。当最后一个包到来时置BOOL bLastPacket为TRUE,判断若listLackPackets中为空,则摘除此链路的所有数据包并保存为文件。每条链路设置一个超时,记录此链路最后一次收到包的时间,若int nLastAcceptTime>=MAX_TIME_OUT还没收到包则删除此链路的所有数据包。以上信息保存按链路号保存在HashTableB中。如下图:
使用一条叫做DispatchThread的线程去轮询HashTableB中的每个链路的包描述符,判断此次通信是否包全部收完,若收完则把此链路号对应于HashTableA中的数据保存在硬盘。
重传机制:
间谍软件的重传机制建立在原收包算法基础上,分为丢包重传和差错重传。数据包中结构体中的包类型为0x03。
接收端:
丢包重传:接收端在接收包后往HashTable中的拉链(链表)插入包时可以知道前面还没接收到的包序号,此时记录这些没收到的包“应该到达的时间”到list结构。“应该到达的时间” 为后面的包到达时间。一旦“应该到达的时间”设置,后面的包到达后不再设置。
在分发线程(即判断一个链路的包收完整就写入磁盘的线程)中,轮询检测每个包是否超时未到达,未到达则发送数据包到对方要求重发。检测包超时方法为如果“当前时间”减去“应该到达的时间”大于等于MAX_TIMEOUT(自己设定的一个值)则为超时,设置此MAX_TIMEOUT时间间隔是考虑到路由选择、拥塞等会影响包到达时间。要求重发后,置“应该到达的时间”+=MAX_REACH(在后面的迭代中会逐步完善MAX_TIMEOUT和MAX_REACH 值)。
差错重传:在收到包后即刻计算数据的checksum与发送过来的描述结构体中的checksum字段对比,若不相等则要求重发。置“应该到达的时间” +=MAX_REACH。
发送端:
发送端使用队列保存发送文件、重发时发送的数据包,先发送的数据包在队首。队列保存足够发送端收到接收端要求重发数据时间差的数据,最少缓存2000个数据包。 当队列满时一次性从队首删除MAX_DELETE个数据包。发送端收到接收端要求重发数据时,依据包中的链路号和包序去队列中查找并发送数据包到对方。
发送端重发时的数据包也保存到队列,当接收端收到发送端重发的数据包时经计算有差错或没收到此数据包时,可以重新请求发送端发送此数据包。
起先考虑用队列加两层Hash表的方法加快发送端处理要求重传数据包的查询速度。但从队列一次性删除MAX_DELETE个数据包时,也需大量的查找,费时间,且要求重传的几率并不高,反而损失性能,所以舍去此种方法。
以下几点是我个人的理解:
1.文件需要按块传输,并且块的大小需要根据网络环境、MTU,包的丢失率几个方面来动态计算控制
2.需要对传输间隔时间进行控制,可以根据网络状态(丢包率为依据)来动态调整传输间隔,好的状态下尽可能缩短,直到丢包率出现。
3.最后一点是建议,如果保证可以有效控制UDP的传输节奏、丢包率、重传率,最好采用UDP,效率上要优于TCP。一是UDP较TCP少了三次握手时间,连接上要优于TCP,二是TCP按顺序传输,并且接受方需要进行校验和确认,过于严格的传输过程,导致灵活性差了些。当然,TCP也有适用的情况,这个要看具体应用了。