在使用 ICS 传文件时,遇到了一些问题,希望有哪个用过相关操作的高人.给我点指点一下.(100分)

  • 主题发起人 主题发起人 QSmile
  • 开始时间 开始时间
Q

QSmile

Unregistered / Unconfirmed
GUEST, unregistred user!
在使用 ICS 传文件时,遇到了一些问题,希望有哪个用过相关操作的高人.给我点指点一下.

我的需要是,从一个 client 向一个 server 发送文件.
用 WSocket 与 WSocketServer
流程是Client先向 Server 发送 文件长度.

然后, Client 把文件以 8K 为一个包向 Server 发送. 没有放到结构体里的.
就直接发送原始数据.

一定发,到发送结束. 然后. server 端
检查接收的长度与文件长度是否相等.
大于或相等,就关闭文件句柄.关闭连接.表示文件接收完成.
while m_FileUpInfo.fStream.Size < m_FileUpInfo.DataLen do
begin
Application.ProcessMessages;
// 超时处理
end;

但我在测试时,发现有时,比如我发一个 21542 byte 的文件,只收到 21540 byte.

差一点点.

这个情况不是每次出现.发 50-100 个文件会出现一次.
而且每次差的字节也不相同.

按道理 TCP 的数据 发送与接收一般不会掉数据呀.只是不会自动分包.

这个如何解决?
那个高手做过.
 
ics我没用过 我用tidtcpserver和tidtcpclient弄了一个感觉还可以 没发现有丢数据的情况
 
我试过一下,发现 Indy 内存泄露.用得有点不放心
 
再顶顶,等待高手的出现
 
我也用ICS传过文件,开始也出现了传输不完整的问题,后来修正了,具体的记不清了.但有一点要注意的是,不要太急着去断开连接,最好等服务器写完所有字节,再通知客户端去主动断开连接.
 
不知道了,我这几兆的数据都一次发过去,一字不少;

你这样试一下啊,尾端多加一些垃圾字符一起发过去;
 
如果采用异步非阻塞方式读取数据,则在断开事件中还要再读一次数据,
因为此时,可能内存缓冲区中可能还有未读取的数据
 
只要不是文本,都应该用流来传送,因为有些字符会被当作截止符被忽略,或者终止连接的!
 
只要不是文本,都应该用流来传送,因为有些字符会被当作截止符被忽略,或者终止连接的!
-----------------
不可能的.又不是串口
 
不知道了,我这几兆的数据都一次发过去,一字不少;

-------------------
??? 是用 ICS 吗?
 
TO: guanyueguan,

能否给点代码片断,或说说你的流程
 
实际上流程很简单,只要在服务端收完数据时再写一个确认给客户端,让客户端去主动断开连接就行了.
有几点可以提醒一下,你的包大小可以放的更大一些都没关系,因为ICS会缓冲重组,这也是我用ICS而不愿用SOCKET API的原因,省去了不少麻烦.另外INDY确实会有些内存泄漏,但主要是SERVER在长时间连接的情况下才容易控制不好出现,非长时间连接用它还不错.
这里就附一段我写的BCB代码吧,我很少用DELPHI,没什么难度,我用它传文件没出现少了字节的.


void __fastcall TfrmFileRec::wsRecDataAvailable(TObject *Sender, WORD ErrCode)
{
if (FRecSize < FFileSize)
{
RecData(wsRec);
}
}
//---------------------------------------------------------------------------

void __fastcall TfrmFileRec::RecData(TWSocket *wsRec)
{
char Buffer[DEF_BUFFERSIZE];
if (FStream == NULL)
{
return;
}
try
{
int nLen = FFileSize - FRecSize > DEF_BUFFERSIZE ? DEF_BUFFERSIZE : FFileSize - FRecSize;
nLen = wsRec->Receive(&Buffer[0], nLen);
if (nLen <= 0)
{
return;
}
FStream->WriteBuffer(Buffer, nLen);
FRecSize += nLen;
if (FRecSize >= FFileSize)
{
wsRec->Send(MSG_TAG_RECOK, strlen(MSG_TAG_RECOK));
ClearData(true);
}
}
catch(Exception &e)
{
if (FRecSize < FFileSize)
{
Application->ShowException(&e);
}
ClearData(false);
}
}
//---------------------------------------------------------------------------
 
我手上有用 Delphi 做的几个例子,(会出现这个问题的例子.)

哪个有兴趣给我看看?
 
发给我帮你看看,dangergy2006@yahoo.com.cn
 
邮件发给你了。多谢

程序有两个部分。一是 serv 。这是服务器端。一是 client
工作方式是。
1, D盘下根目录要有一个 1.exe ,比较大的那种。
2, 先启动serv 。
3. 再启动 client ,把 client 连接到 serv 上。serv 就开始向 client 发数据。(文件)
4. client 收到数据后。写入 c:/1.exe (没做数据校验与其它)

问题是:有时收到的数据要比发送的数据多 19 个字节。很固定,每次多都多 19 个字节。要么就不多。
还有好象本机试没有问题,用局域网试就会有这样的问题,不是每次出现,但发的文件比较大时,比现的机率也比较大.

 
 
已经修改好了,邮件发出去了,不会再出现多19个字节的问题了,我只增加了一行代码.
在Server FormCreate里增加一行
svr1.Banner := '';
 
多人接受答案了。
 
后退
顶部