DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: li739139899
今日帖子: 7
在线用户: 2
导航: 论坛 -> 网络通讯 斑竹:liumazi,sephil  
作者:
男 crestxa (crestxa) ▲▲▲▲△ -
注册会员
2019/4/3 7:47:19
标题:
TCP接收大量数据的问题 浏览:621
加入我的收藏
楼主: 需要接收和发送大量数据,(600K),但是IdTCPServer每次只能接收一部分,本来想拼接起来,但是过程太容易出错了,怎么能全部接收呢。有没有相应的例子,谢谢!
----------------------------------------------
-
作者:
男 keymark (keymark) ▲△△△△ -
注册会员
2019/4/3 8:03:23
1楼: 嘻哈 序列 长度 数据
MTU 1500字节   发1024字节 比较好。
----------------------------------------------
m3u8播放器:DPlayer/hlsjs-p2p-engine/ckplayer/flashls-dev/sewise-player/http不能播https某些情况下dns服务:coredns/http服务:miniweb/!http://www.lib4dev.com/topics/delphi>http://www.lib4dev.com/topics/pascal?p=34&s=!http://www.lib4dev.com/topics/delphi
作者:
男 joman (joman) ▲▲▲△△ -
注册会员
2019/4/3 8:06:28
2楼: 组包 头尾长度包体
----------------------------------------------
DelphiWebMVC官网 http://www.delphiwebmvc.com
作者:
男 crestxa (crestxa) ▲▲▲▲△ -
注册会员
2019/4/3 8:44:43
3楼: keymark:发的字节没法控制,是硬件已经决定了,一次发过来那么多,上位机只能被动接收。
joman :地下发过来的有帧头帧尾,但是数据量有点大,一次接收不了,容易出问题,导致没法组成帧。有没有相应的实例,谢谢!
----------------------------------------------
-
作者:
男 abcjingtong (jingtong) ▲▲▲▲▲ -
注册会员
2019/4/3 9:20:39
4楼: tcp的粘包问题,到处是实例。既然有帧头和帧尾了已经是很标准的模式了:
1.tcp收到数据后放入接收缓冲区
2.从接收缓冲开始,取帧头长度的数据,和帧头比较一下是否相同,如果相同标记新数据开始,如果大小不足600K,则将接收缓冲区的数据移入数据缓冲区;
3.继续接收,判断收到的长度和数据缓冲区的现有长度相加是否到了600K,没到就把接收到的放到数据缓冲区尾;如果相加>=600K,则数据缓冲区凑整600K后触发收到完整帧的事件,如果相加>600K,要将和原数据缓冲区补齐600K后剩余的数据重新做为数据开始;
4.重新第1步;
----------------------------------------------
18114532@qq.com
作者:
男 joman (joman) ▲▲▲△△ -
注册会员
2019/4/3 11:21:17
5楼: 要自己组装,比如你的 有效长度是10 你可能接了15个字节 你只取10个剩下5个存储再接后面的累加,可能是20了,还是只取10个 只要符合长度和头尾的,剩余的下次再累加 ,两个线程 一个取一个算
----------------------------------------------
DelphiWebMVC官网 http://www.delphiwebmvc.com
作者:
男 bahamut8348 (leonna) ★☆☆☆☆ -
普通会员
2019/4/3 11:25:13
6楼: 首先,tcp协议粘包和分包是很正常的。
第二,你用indy做服务端么?这个就祝你好运了。
----------------------------------------------
--
作者:
男 crestxa (crestxa) ▲▲▲▲△ -
注册会员
2019/4/3 15:15:53
7楼: bahamut8348

难度INDY是个坑?
那你们一般用什么做服务器,谢谢!
----------------------------------------------
-
作者:
男 bahamut8348 (leonna) ★☆☆☆☆ -
普通会员
2019/4/3 18:20:55
8楼: 一般做服务端程序,我首先就会把delphi排除在外。
这种一言不合就抛异常的东西,还真是不好惹。
还有就是,在这方面,delphi可用的三方资源太少。

给你个方案:
一:最快速的方案就是使用nginx或者apache这种开放式的成熟高可用性的服务端去处理数据收发,你只需要关注业务部分就可以了。
二:使用开放的三方库,个人建议是libev或者libevent,开源跨平台。
三:如果你一定要吊死在delphi上,建议你去看看mORMot这个三方库。
四:如果你一定要自己折腾的话,直接用select模型做tcp是做不起来的。建议你去看看网络模型;windows系统去研究研究iocp模型,linux去研究研究epoll,freebsd上去研究研究kqueue。
----------------------------------------------
--
作者:
男 dbyoung (dbyoung) ★☆☆☆☆ -
普通会员
2019/4/3 18:50:42
9楼: 我客户端、服务端一直用 Delphi,7*24运行良好。
Delphi有源代码,不知道修改吗?
indy 抛的异常,可以将抛异常的源代码复制到本目录下,进行修改(2个文件)。

第三方控件的BUG,比 Delphi 自带的代码BUG,多多了。
----------------------------------------------
Delphi7爱好者
作者:
男 feiyanm (feiyanm) ▲▲▲△△ -
注册会员
2019/4/4 7:41:36
10楼: 想省事,用8楼,想费劲,用9楼。水平不行的话,8楼9楼都没用。
----------------------------------------------
Delphi威武!千秋万代,一统江湖!Delphi威武!千秋万代,一统江湖!Delphi威武!千秋万代,一统江湖!Delphi威武!千秋万代,一统江湖!Delphi威武!千秋万代,一统江湖!Delphi威武!千秋万代,一统江湖!Delphi威武!千秋万代,一统江湖!我去WC吐一会儿去!
作者:
男 wang_80919 (Flying Wang) ▲▲▲▲▲ -
普通会员
2019/4/4 9:09:26
11楼: 抛异常是好事啊。说明开发人员认真。
我们懒人写的,就不抛异常,瞎执行。不能执行,也强行执行。

而且 我 8 楼 9 楼的 都没用上。
说明我不仅仅懒,水平还低。
----------------------------------------------
(C)(P)Flying Wang
作者:
男 crestxa (crestxa) ▲▲▲▲△ -
注册会员
2019/4/4 10:24:48
12楼: 我只是传个数据,没那么复杂,可能我水平不行,目前遇到的问题确实比较多,IdTCPServer动不动就假死
----------------------------------------------
-
作者:
男 bahamut8348 (leonna) ★☆☆☆☆ -
普通会员
2019/4/4 11:09:44
13楼: 不抛异常不表示就不管错误。去参照一下win32的api是怎么报错的。
至于能运行良好,如果没执行几次逻辑,只要没有明显错误的程序都可以运行良好。
也别扯什么改人家代码,我有那个时间不如找个更稳定、扩展性更强的。而且还跨平台。

至于楼主的问题,8楼已经说了,不在重复了。
----------------------------------------------
--
作者:
男 hnxxcxg (咏南中间件) ★☆☆☆☆ -
盒子活跃会员
2019/4/4 11:16:48
14楼: idtcpserver根本不存在粘包问题
----------------------------------------------
咏南中间件 QQ:254072148http://www.cnblogs.com/hnxxcxg/
作者:
男 crestxa (crestxa) ▲▲▲▲△ -
注册会员
2019/4/4 18:36:54
15楼: 14楼,是存在的,比如发送那边发个10K的数据过来,这边接收的时候可能是1+1+8,也可能是2+3+5等各种组合,但是不会一次收10K
----------------------------------------------
-
作者:
男 pcplayer (pcplayer) ★☆☆☆☆ -
普通会员
2019/4/15 3:18:37
16楼: 沾包这个说法,明显是不懂 TCP 的人发明的。TCP 就是根水管,里面都是流。这个流如何断句,那是你自己的问题,不是 TCP 的问题。

抛异常是非常好的代码模式。如果程序有异常但你要继续执行,你把异常处理好就行了。不是说有异常程序就会中断或者就会崩溃。用 TIdTCP 那一套控件的话,你把异常处理好了,连续运行不会有事的。俺对 TIdTCPServer 做过压力测试。

15楼,一次收多少个数据不是问题。问题是你要知道你应该收多少数据。假设你知道你应该收 4096 个Byte,那么,你创建一个流(TStream),收到几个就丢进去几个,收够为止。不就完了?二进制字节流的处理,概念其实很简单。
----------------------------------------------
-
作者:
男 keymark (keymark) ▲△△△△ -
注册会员
2019/4/15 9:36:04
17楼: 听大佬说过 包可能会错序 。。有这回事吗?
----------------------------------------------
m3u8播放器:DPlayer/hlsjs-p2p-engine/ckplayer/flashls-dev/sewise-player/http不能播https某些情况下dns服务:coredns/http服务:miniweb/!http://www.lib4dev.com/topics/delphi>http://www.lib4dev.com/topics/pascal?p=34&s=!http://www.lib4dev.com/topics/delphi
作者:
男 gmxyb (gmxyb) ▲▲▲▲△ -
注册会员
2019/4/15 9:49:39
18楼: 赞同16楼,划重点:

【沾包这个说法,明显是不懂 TCP 的人发明的。TCP 就是根水管,里面都是流。这个流如何断句,那是你自己的问题,不是 TCP 的问题。】


至于17楼说的“包可能会错序”,这也是不懂 TCP 的“大佬”在胡说八道、信口开河。。
----------------------------------------------
-
作者:
男 wang_80919 (Flying Wang) ▲▲▲▲▲ -
普通会员
2019/4/15 10:44:10
19楼: 顶 16 18 楼。

TCP 的问题在于,另一头说 打算发 100个字节给我。
我说,我知道了,你发吧。
结果,对方发了 99 个不发了。
我怎么办?我只能等啊。所以,有一个 超时。
多长时间,对方不发数据,就会超时。
超时,我也只能等啊。
万一我放弃了,对方突然发过来呢。

不过,喜欢的话,可以通知对方,老子不等了,断开连接,剩余的数据 老子不要了。
你爱发不发。
我重新发起一次请求。
这次 你还超时。
我提示 ,对方 无响应!

http 就是 简单的 tcp 。
post get put head 四个命令而已。
ftp 命令就多一些。
都是 TCP 应用。
http 喜欢不保持连接。
比如发一个 GET 命令,接收完数据,就断开了。
服务器 想 主动 发点数据,都不知道该怎么发。

FTP 不一样,需要 一直连着。

不过  FTP 一样是 客户端 提交 请求的,服务器 才会 回复。人家 从来就没打算 服务器 主动发消息给 FTP 客户端。

http 表现出 一直联网的方法就是 ajax。简单的说,就是 轮询。

轮询,到了手机上,就是 费电。非常费电。
所以 各个厂家,都希望 APP 不要轮询。

腾讯 只好 和 各个厂家 要 他们的 接口 API。
谷歌 苹果的 接口比较通用。
但是 很多厂家,也有自己的接口。
用 接口 API ,实现 推送。 是 腾讯的做法。
但是 腾讯 收集的接口多了,也就开发出自己的 推送 服务器了。
给那些 厂家 懒得做自己接口的手机用。

极光等第三方,也是一样的道理。
他们 也是 和 各个厂家 要 API 。然后 自己的 推送服务器 负责 那些 没有 API 的厂家。
----------------------------------------------
(C)(P)Flying Wang
作者:
男 chonghai (DBlue) ★☆☆☆☆ -
盒子活跃会员
2019/4/15 11:42:37
20楼: 学习了!
----------------------------------------------
喜欢Delphi,关注Delphi,愿和广大爱好者交朋友。
作者:
男 mousesoft (MouseSoft) ★☆☆☆☆ -
盒子活跃会员
2019/4/15 12:28:56
21楼: 粘包,也许是在客户端发送的时候就粘包发送了呢?,查清楚,在根上找原因
----------------------------------------------
http://www.nkaixin.com
作者:
男 hdcopy (hdcopy) ▲▲▲▲▲ -
普通会员
2019/4/16 11:30:24
22楼: 接收设备的数据,以及网络不好,才会有这类问题。

说好发8K,PC真的就会一次发8K,不管网络上传输时被拆成什么样子(MTU),
收到的时候都是拼好的。
设备发的话,可能就会一会儿发4K,一会儿发5K(带着下一个包的数据)。

SERVER通常也不会设置很长的超时。

但,不管数据包多大,4楼的做法不是挺好的吗?
收数据,添加到缓存区末尾,取现在缓存区长度,大于包长度后取包出来处理;
缓存区移除处理的包的数据,剩余数据整体MOVE到开头,调整缓存区长度。
剩余数据长度大于包头长度,取下一个包的长度,看剩余数据长度是否大于缓存区长度,如大于,取包出来处理直到剩余长度不足等待接收数据
----------------------------------------------
-
作者:
男 wang_80919 (Flying Wang) ▲▲▲▲▲ -
普通会员
2019/4/16 12:02:38
23楼: 第三方都做好的事情,非要自己写代码。都是牛人。
----------------------------------------------
(C)(P)Flying Wang
作者:
男 bigboy2050 (bigboy2050) ▲▲▲▲▲ -
注册会员
2019/4/18 13:04:04
24楼: indy 很好啊,谁在黑我们的伟大的 indy!
----------------------------------------------
http://www.kittyapp.net
作者:
男 crestxa (crestxa) ▲▲▲▲△ -
注册会员
2019/4/18 14:33:07
25楼: 24楼,有没有用indy做的收发数据的例子,学习一下,谢谢!
----------------------------------------------
-
作者:
男 pcplayer (pcplayer) ★☆☆☆☆ -
普通会员
2019/4/22 1:55:47
26楼: 25楼,Indy 官方的 Demo 很多,去网上搜。其他人写的例子代码网上也很多。我老人家也在网上发过用 Indy 写的例子代码。

21 楼,你说的【粘包,也许是在客户端发送的时候就粘包发送了呢?】,这个是不存在的。再重复一遍,TCP 没有粘包这个荒谬的概念。

在客户端,假设你要发送2个包,每个包100字节。你可以100字节发完,再发100字节,看起来是发了2个包。你也可以一个字节一个字节地发,发完200个字节为止。你也可以一会发10个字节,一会发20个字节。随便你,都没关系。你用 Delphi 发出去的字节,都会存入 Windows 底层的 TCP/IP 协议栈里面给你开的 buffer,然后呢,Windows 看网络速度如何,网络速度快它发得快,网络速度慢它发得慢。至于它发出去的数据是一个一个的字节还是一个一个的包,在 TCP 层来看,所谓的包是不存在的,没有意义的。就是一个一个字节的字节流。
----------------------------------------------
-
作者:
男 wang_80919 (Flying Wang) ▲▲▲▲▲ -
普通会员
2019/4/22 8:57:26
27楼: d7 时代的 网络程序用 INDY 很多啊。
那时候 一个 server 一个 client 两个 exe ,标准的 cs 人家运行得也很好啊。
----------------------------------------------
(C)(P)Flying Wang
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v2.1 版权所有 页面执行21.48438毫秒 RSS