| 网站首页 | 业界新闻 | 小组 | 交易 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
Reworld,下班在家制作游戏,1500万奖金等你拿以码会友 以友辅仁
共有 272 人关注过本帖
标题:VFP socket 接收超过10000个字符的数据会出现数据不全的现像,导致数据不全
只看楼主 加入收藏
laibinhua
Rank: 1
等 级:新手上路
帖 子:44
专家分:0
注 册:2010-12-23
结帖率:50%
  已结贴   问题点数:18  回复次数:8   
VFP socket 接收超过10000个字符的数据会出现数据不全的现像,导致数据不全
VFP socket 接收超过10000个字符的数据会出现数据不全的现像,导致数据不全,有时全,有是不全!有什么好办法解决吗?
DataArrival:
*** ActiveX Control Event ***
LPARAMETERS BytesTotal
LOCAL lcBuffer
lcBuffer=SPACE(BytesTotal)

**获得所接收到的数据
This.object.GetData(@lcBuffer)
Thisform.pf1.p1.txtOutput1.Value = lcBuffer

[此贴子已经被作者于2019-9-23 17:24编辑过]

搜索更多相关主题的帖子: socket VFP 数据 出现 接收 
2019-09-23 15:44
laibinhua
Rank: 1
等 级:新手上路
帖 子:44
专家分:0
注 册:2010-12-23
  得分:0 
回复 楼主 laibinhua
网上找了下资料 是winsock控件默认缓冲区的问题。如果大于8k也会传。 不过对方会收到几个数据到达事件 8*1024 超过后有办法处理吗?
2019-09-23 21:19
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:209
帖 子:6722
专家分:29743
注 册:2014-5-20
  得分:9 
应该不是数据大小的问题
说说“出现数据不全”的具体表现
提供测试数据和代码才好分析问题
2019-09-24 05:03
laibinhua
Rank: 1
等 级:新手上路
帖 子:44
专家分:0
注 册:2010-12-23
  得分:0 
回复 3楼 吹水佬
谢谢你的回复,代码如下:用的是winsock组件,数据包格式见附件,超过8K大小的字符串
winsock做成类它的dataArrival事件如下:
*** ActiveX Control Event ***
LPARAMETERS bytestotal
lcData=SPACE(bytestotal)
this.object.getData(@lcData)
thisform.when_receive_data(this.Parent.Name,lcData)

把类放入表单,表单的 when_receive_data事件如下:
LPARAMETERS tcWinsockName,tcData
thisform.pf1.p1.txtOutput1.Value =tcData  &&取到数据

上面就是主要的代码,数据不超过8K时,接收正常,超过时就经常不完整
附件: 您没有浏览附件的权限,请 登录注册
2019-09-24 09:15
laibinhua
Rank: 1
等 级:新手上路
帖 子:44
专家分:0
注 册:2010-12-23
  得分:0 
回复 4楼 laibinhua
原因找到了,其实是SOCKET 客户端发过来的字符超过8K时自动拆分成多个包了,SOCKET服务端分批收取了数据,只是不知道如何拼包合并包,老师有什么办法合并包吗?
2019-09-24 14:16
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:209
帖 子:6722
专家分:29743
注 册:2014-5-20
  得分:0 
以下是引用laibinhua在2019-9-24 14:16:30的发言:

原因找到了,其实是SOCKET 客户端发过来的字符超过8K时自动拆分成多个包了,SOCKET服务端分批收取了数据,只是不知道如何拼包合并包,老师有什么办法合并包吗?

好多时每次 send 是不等于 recv 的。
不好意思,没用winsock组件。通常传送数据用TCP协议的多,可以参考相关TCP/IP协议发送与接收方面的资料。
以传送文件简单说一下,用C语言来表达,VFP调用winsock API来写也可以。

//发送端
//循环发送数据,直到文件结尾
char buffer[BUF_SIZE] = {0};    //缓冲区
int nCount;
while ((nCount = fread(buffer, 1, BUF_SIZE, fp)) > 0 )
{
    send(clntSock, buffer, nCount, 0);
}
shutdown(clntSock, SD_SEND);    //文件读取完毕,断开输出流,向客户端发送FIN包
recv(clntSock, buffer, BUF_SIZE, 0);    //阻塞,等待客户端接收完毕
fclose(fp);
closesocket(clntSock);
closesocket(servSock);
WSACleanup();

//接收端
//循环接收接收,直到文件传输完毕
char buffer[BUF_SIZE] = {0}; //文件缓冲区
int nCount;
while ((nCount = recv(sock, buffer, BUF_SIZE, 0)) > 0 )
{
    fwrite(buffer, nCount, 1, fp);
}
fclose(fp);
closesocket(sock);
WSACleanup();

问题重点理解几点:
close()、closesocket()、shutdown() 和 FIN 包
close() 和 closesocket() 用来关闭套接字,之后不能使用该套接字。关闭套接字后,与该套接字相关的连接和缓存也失效。
shutdown() 用来关闭连接,而不关闭套接字。
调用 close()、closesocket() 关闭套接字,或调用 shutdown() 关闭输出流时,都会向对方发送 FIN 包。
FIN 包表示数据传输完毕,计算机收到 FIN 包就知道不会再有数据传送过来了。
默认情况下 close()、closesocket() 会立即发送FIN包,不管输出缓冲区中是否还有数据,而shutdown() 会等输出缓冲区中的数据传输完毕再发送FIN包。也就意味着,调用 close()、closesocket() 将丢失输出缓冲区中的数据,而调用 shutdown() 不会。


[此贴子已经被作者于2019-9-25 06:21编辑过]

2019-09-25 06:19
laibinhua
Rank: 1
等 级:新手上路
帖 子:44
专家分:0
注 册:2010-12-23
  得分:0 
回复 6楼 吹水佬
谢谢 你的回复!已解决了!DataArrival事件中本身可以自动分段接收数据,只要在这里面加个数据完整性的检查,如果数据不完整就把接到的字符做拼接,如果数据全了就跳出这个事件,执行一个自定义的事件!
2019-09-25 15:51
sostemp
Rank: 2
等 级:论坛游民
威 望:1
帖 子:33
专家分:34
注 册:2009-6-2
  得分:9 
回复 7楼 laibinhua
能不能上个解决示例
2019-09-26 08:46
xmwld
Rank: 1
等 级:新手上路
帖 子:16
专家分:7
注 册:2010-11-13
  得分:0 
精彩案例,值得学习
3 天前 17:24
快速回复:VFP socket 接收超过10000个字符的数据会出现数据不全的现像,导致数据 ...
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.027219 second(s), 8 queries.
Copyright©2004-2019, BCCN.NET, All Rights Reserved