DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: chencs1988
今日帖子: 42
在线用户: 11
导航: 论坛 -> 网络通讯 斑竹:liumazi,sephil  
作者:
男 zhyhero (zhyhero) ★☆☆☆☆ -
盒子活跃会员
2021/4/7 12:16:04
标题:
NetCom7初步研究 浏览:1530
加入我的收藏
楼主: NetCom7是一套TCP协议通讯实现组件,基本特性(线程实现和池,同步异步)可以阅读一下自带的说明文档,这里主要初步研究了一下ncClientSource和ncServerSource,参考了自带的Demo。

ncServerSource设置Port,设置Active开始监听。
ncClientSource设置Host和Port,设置Active连接远端的ncServerSource。

ncServerSource的OnConnected,OnDisConnected分别表示远端ncClientSource连接和断开的事件。
ncClientSource的OnConnected,OnDisConnected,OnReConnected分别表示与远端ncServerSource的连接,断开,重新连接事件。
ncClientSource可以设置定时自动ReConnect,不要人工干预。
这些不需要刻意关注。

ncServerSource的OnHandleCommand和OnAsyncExecCommandResult用来处理远端ncClientSource的ExecCommand指令,通过该指令的aAsyncExecute参数来决定匹配对应的事件。
OnHandleCommand事件处理过程有以下几种
1.返回result给ncClientSource.ExecCommand。与ncClientSource.ExecCommand的aRequiresResult参数有关。
2.通过raise抛出异常方式返回到Try...Except包裹的 ncClientSource.ExecCommand代码段。与ncClientSource.ExecCommand的aRequiresResult参数有关。
3.ncServerSource.ExecCommand(aLine)发送讯息给ncClientSource.
OnAsyncExecCommandResult事件处理应该类似于OnHandleCommand事件。

ncClientSource的OnHandleCommand和OnAsyncExecCommandResult与ncServerSource的相同。

aLine对象表示对端。即对于ncClientSource来说aLine表示远端的ncServerSource Peer.反之亦然。
aCmd表示指令值。
aData表示传输的数据。

ncServerSource.Lines表示远端ncClientSource Peer的集合。
此帖子包含附件:
PNG 图像
大小:50.0K
----------------------------------------------
-
作者:
男 jackalan (nVicen) ★☆☆☆☆ -
盒子活跃会员
2021/4/7 13:55:38
1楼: 看过一段时间,感觉这个组件逻辑没有INDY清晰。
尤其要传输大数据流的时候
----------------------------------------------
简单做人,认真做事。
作者:
男 zhyhero (zhyhero) ★☆☆☆☆ -
盒子活跃会员
2021/4/7 14:09:31
2楼: @1楼
把大数据流分成多个块(aData),用ExecCommand指令把这些块(aData)依次传过去,远端接收以后再组装上。
----------------------------------------------
-
作者:
男 pcplayer (pcplayer) ★☆☆☆☆ -
普通会员
2021/4/7 19:33:34
3楼: 楼上,大数据分块然后自己组合,这种思路不主流。

看看 FTP 的实现:字节流。

FTP 的续传:字节位置。

也可以把它看成块,只不过这个块的大小是一个字节。
----------------------------------------------
-
作者:
男 sail2000 (小帆工作室) ★☆☆☆☆ -
盒子活跃会员
2021/4/7 20:32:28
4楼: 然而,自带的对比测试结果---->比 INDY 慢,
依次分别是1W,10W,100W
此帖子包含附件:
PNG 图像
大小:12.1K
----------------------------------------------
delphi 是兴趣,和工作无关,即使它倒闭。
又不靠它 delphi 吃饭,怕甚?
作者:
男 zhyhero (zhyhero) ★☆☆☆☆ -
盒子活跃会员
2021/4/8 4:15:20
5楼: 我也做了一下测试 64位编译 两台实体机器之间传输,客户端BuffSize=2048。

NetCom 峰值速率 980+ Mbps
Indy   峰值速率 50+  Mbps

BuffSize 我试了好几个值,最大试到10240 .
结果是NetCom 在1536就可以跑到峰值980+ Mbps了。Indy最高跑到155+ Mbps。
上面的对比结果仅限 NetCom Vs Indy这个Demo。
此帖子包含附件:
PNG 图像
大小:6.8K
----------------------------------------------
-
作者:
男 magiewang (magiewang) ▲▲△△△ -
注册会员
2021/4/8 9:07:20
6楼: 上次就想用这个控件做个大文件传输,不知道该怎么用,它虽然也支持阻塞模式,但数据传达都是触发事件,楼上大侠能给个例子吗?带进度条的文件传输。。。
----------------------------------------------
-
作者:
男 pcplayer (pcplayer) ★☆☆☆☆ -
普通会员
2021/4/8 12:17:30
7楼: 如果 Indy 能用的话,为啥一定要用 NetCom 这个控件?

我实际测试,Indy 在 Windows / Android /iOS 底下,用起来都没问题。

我是用 Indy TCP 来跑网络视频流,感觉很正常。
----------------------------------------------
-
作者:
男 zhyhero (zhyhero) ★☆☆☆☆ -
盒子活跃会员
2021/4/8 12:42:37
7楼: @6楼

关于更新UI,对于接收端(Server或Client)来说,在OnHandleCommand事件里,调用TThread.Queue或者TThread.Synchronize方法,执行你要更新UI的过程。

参见它自带的Demo(ChatDemo),有个更新UI的过程。
procedure TfrmMain.Log(aStr: string);
begin
  // This is thread safe
  TThread.Queue(nil,          //这里或者用TThread.Synchronize
    procedure
    begin
      memLog.Lines.Add(aStr);
      memLog.ScrollBy(0, 100);
    end);
end;

对于发送端(Server或Client)来说,
A.在执行ExecCommand(aRequiresResult=true)方法处,确认Result(接收端的OnHandleCommand事件返回结果)之后,更新UI(应该不需要调用TThread.Queue或者TThread.Synchronize方法),或者忽略Result直接更新UI.
B.在执行ExecCommand(aRequiresResult=false)方法后,接收端的OnHandleCommand事件内部处理数据之后,接收端执行ExecCommand发送结果给发送端,发送端的OnHandleCommand事件内部确认结果调用TThread.Queue或者TThread.Synchronize方法,执行你要更新UI的过程。
C.或者其它非常方式,例如 raise.

关于文件传输,发送端把文件读入FileStream,然后以BuffSize为单位块大小(根据上面我测试的结果,低于1536会以较低的速度传输)分块(Block)依次读取,填入一个长度为BuffSize的TArray<Byte>类型的数组,传给ExecCommand的aData(TArray<Byte>),接收端在OnHandleCommand事件里,确认是文件传输,预先准备个BufferedFileStream,然后依次把接收到的aData写入BufferedFileStream。

其它的什么FileStream.size,FileStream.Position等自行考量使用。

写的比较乱,请大家见谅。
----------------------------------------------
-
作者:
男 zhyhero (zhyhero) ★☆☆☆☆ -
盒子活跃会员
2021/4/8 12:45:23
8楼: @7楼pcplayer 
恰好研究到了而已,学习一下这玩意到底怎么用,没其它的意思。
----------------------------------------------
-
作者:
男 xiaobaosoft (小宝软件) ▲△△△△ -
注册会员
2021/4/9 1:15:35
9楼: 都2021年了  居然还要手动组包。。。
----------------------------------------------
-
作者:
男 scarlette (Scarlette) ★☆☆☆☆ -
普通会员
2021/4/9 10:43:01
10楼: 楼上的,自己组包才是正常的!一个TCP组件,就应该完全透明的传输原始数据,能发的发,不能一次发的缓冲起来一点点发;难道还要给你加他自己的分割协议?和其他不用这组件写的TCP端点不用互联了?
----------------------------------------------
-
作者:
男 xiaobaosoft (小宝软件) ▲△△△△ -
注册会员
2021/4/9 13:04:07
11楼: @scarlette

不知道有个东西叫Pack么。

目前先进点的TCP组件 基本都有pack模式  组件自行完成组包和拆包 不需要关心粘包问题

发什么收到就是什么。
----------------------------------------------
-
作者:
男 scarlette (Scarlette) ★☆☆☆☆ -
普通会员
2021/4/9 14:46:13
12楼: @ xiaobaosoft (小宝软件):
我晕,你跟我说的是一回事儿吗?粘包和切片策略完全是两件事儿啊,前面说的是巨大数据块的切片策略好吧。你非要一趟头扔给组件10个G的数据理论上也可以,可实际中有人这么搞吗?
----------------------------------------------
-
作者:
男 littlestone08 (littlestone08) ★☆☆☆☆ -
普通会员
2021/4/10 7:48:22
13楼: 留名
----------------------------------------------
我和我追逐的梦,擦肩而过
作者:
男 xiaobaosoft (小宝软件) ▲△△△△ -
注册会员
2021/4/11 20:25:04
14楼: @scarlette

我是针对你说  自己组包切片才是正常的这句话

我的意思是 应该让组件来做 而不是自己来做。这样才是进步的 。并且也已经有很多库这么做了。

当然你也可以自己组包 切片  但是他们提供了这个方法。
----------------------------------------------
-
作者:
男 sail2000 (小帆工作室) ★☆☆☆☆ -
盒子活跃会员
2021/5/4 10:32:26
15楼: 请教一下楼主:
我尝试用 ExecCommand 发送文件,我确定发送的字节数是对的,但 server 接收那边的字节数不对,写入文件后有很多冗余字节,我百思不得其解。
是需要在 server 接收那边额外计算吗?

系统:Win10/x64
IDE:Delphi 10.4.2

附件是 7zip 格式
此帖子包含附件:sail2000_202154103122.zip 大小:5.59M
----------------------------------------------
delphi 是兴趣,和工作无关,即使它倒闭。
又不靠它 delphi 吃饭,怕甚?
作者:
男 keymark (嬲) ▲▲△△△ -
注册会员
2021/5/4 12:36:35
16楼: 154 KB (157,937 字节)

  BS.LoadFromFile('client.png');

  // 发送文件大小
   Memo1.Lines.Add('Length(BS.Bytes)   发送文件大小:' + Length(BS.Bytes).ToString);
最后 ~然后我在这dump了下BS.Bytes内存  和 服务端接收到的一样!!问题追踪完毕
   Memo1.Lines.Add('BS.Size          发送文件大小:' + BS.Size.ToString);

Length(BS.Bytes)   发送文件大小:163840
BS.Size          发送文件大小:157937

BS.Size          服务器接收数据大小:163840
Length(BS.Bytes) 服务器接收数据大小:163840
到底是谁的锅 谁背呢。


当代码来到
function TncCommand.ToBytes: TBytes;

DataBytesLen := Length(Data);


好我们再看下
constructor TBytesStream.Create(const ABytes: TBytes);
begin
  inherited Create;
  FBytes := ABytes;
  SetPointer(Pointer(FBytes), Length(FBytes));
Length(FBytes)!!!!!!!!!!
----------------------------------------------
git config --global alias.co 'clone --recurse-submodules'
git config --global alias.up 'submodule update --init --recursive'
懒鬼提速
http://qalculate.github.io/downloads.html
https://www.cctry.com/
作者:
男 keymark (嬲) ▲▲△△△ -
注册会员
2021/5/4 13:41:20
17楼:
function TBytesStream.Realloc(var NewCapacity: Longint): Pointer;
  if (NewCapacity > 0) and (NewCapacity <> FSize) then
    NewCapacity := (NewCapacity + (MemoryDelta - 1)) and not (MemoryDelta - 1); !!呵呵 在这开内存 Bytes重算大小
----------------------------------------------
git config --global alias.co 'clone --recurse-submodules'
git config --global alias.up 'submodule update --init --recursive'
懒鬼提速
http://qalculate.github.io/downloads.html
https://www.cctry.com/
作者:
男 sail2000 (小帆工作室) ★☆☆☆☆ -
盒子活跃会员
2021/5/5 7:39:40
0楼: 唉,我不单太懒了,技术也太烂了。
----------------------------------------------
delphi 是兴趣,和工作无关,即使它倒闭。
又不靠它 delphi 吃饭,怕甚?
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v2.1 版权所有 页面执行31.25毫秒 RSS