客户端如何才能知道服务器端的数据已经发送完毕了?

leojay 2005-04-18 03:58:00
阻塞式的socket,我怎么才能知道服务器端的数据已经发送完毕了?

比方说服务器发送了1MB的数据过来。
我的客户端的buffer只有10K。
这种情况的程序应该怎么写呢?

char buffer[10240];
do {
iRead = recv(m_client,buffer,10240,0);
fwrite( buffer, 1, iRead, fp );
}while( iRead == 10240 );

这样写可以吗?

如果服务器端发送16K的数据,是不是一定先收到10K再收到6K,有没有可能先收到9K再收到7K呢?如果有可能的话,我上面的写法就应该有问题了。

如果服务器端发送的数据跟我的buffer大小刚好一样,也就是说,我第一次把数据都收下来了,然后再调用recv的话,程序就阻塞了。这个应该怎么办啊?

...全文
648 23 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
Caps77 2005-04-22
  • 打赏
  • 举报
回复
tcp的NAGLE算法优化了数据发送,只有当缓存满了以后才发送数据,并不是你一send就发送。如果关闭了NAGLE算法(使用setsockopt设置TCP_NODELAY选项),实际上发送次数和你调用send函数次数一样,发多少就出去多少。。
leojay 2005-04-22
  • 打赏
  • 举报
回复
好吧。这个问题我了解了。

那么,还有一个问题,如果我客户端的Buffer是10K,服务器端发送16K的数据,那么客户端是不是一定先收到10K再收到6K,有没有可能先收到9K再收到7K呢?
llm06 2005-04-22
  • 打赏
  • 举报
回复
你的目的是什么呢?

自己打包呀,收到包尾不就知道数据发送完成了吗
一条晚起的虫 2005-04-22
  • 打赏
  • 举报
回复
没有数据长度的,应该有固定的结束格式
danfeng 2005-04-21
  • 打赏
  • 举报
回复
定义好包头,包头包含数据体的长度,客户端先接收包头,再根据里面的长度来接收数据体
leojay 2005-04-21
  • 打赏
  • 举报
回复
自己顶。

如果服务器端没有说要发送多少条数据,就是send了一大笔数据。那么客户端这边有没有可能知道什么时候这笔数据收完了?
Practise_Think 2005-04-21
  • 打赏
  • 举报
回复
这是自己定义的协议决定的,这就像两个人聊Q一样,如果对方不发"88",或者事前对方不说好跟你聊多少句话,判断对方不会再发数据的方法是,要么它已经下线了(客户端与服务端断开),要么对方很长时间也不发数据过来(超时),不然的话就不能断定服务端不发数据了!!
leojay 2005-04-21
  • 打赏
  • 举报
回复
To Caps77(厉兵秣马):
这样不行吧,超时设多少呢,设长的话要等很长时间,设很短的话,收不到数据。
leojay 2005-04-21
  • 打赏
  • 举报
回复
就像HTTP协议,有一些HTTP服务器就不会返回数据的长度的。那应该怎么办呢?
Caps77 2005-04-21
  • 打赏
  • 举报
回复
可以用select设置一个超时,一段时间没有数据,退出循环
agent 2005-04-21
  • 打赏
  • 举报
回复
没错,如果客户端需要知道何时数据发完,就要事先知道要接收的数据长度。
llm06 2005-04-19
  • 打赏
  • 举报
回复
自己加头尾,打包,客户端收到数据后解包。
leojay 2005-04-19
  • 打赏
  • 举报
回复
我了解大家的意思了。

大家的意思好像就是说,要服务器端先说一共有多少个数据要发送,然后再发送具体的数据,最后再加一个校验。

我一开始想问的就是。如果服务器端没有说要发送多少条数据,就是send了一大笔数据。那么客户端这边有没有可能知道什么时候这笔数据收完了。

tanggt006 2005-04-19
  • 打赏
  • 举报
回复
自定义一个包头与包体,当服务器发送完成,由包头来完成这个任务
HZ_Ring 2005-04-19
  • 打赏
  • 举报
回复
先要知道对方发送的长度,然后用循环语句检测当收到的长度够了就停止发送
gloomyfish 2005-04-19
  • 打赏
  • 举报
回复
tcp会根据网络的流量自动分片,你定义的缓冲大小并不代表每次socket会按你的要求去做
你可以数据的头尾标志,自己做校验,正如"漂人"所说~~~~~~~~~~~`
nuaawenlin 2005-04-19
  • 打赏
  • 举报
回复
你可以将所有的iRead 加起来等于1m不就可以了吗???

每次你接收到的数据量是不一样的,并且可能分多次到达,所以你最好把每次接收到的数据量
相加

不过最好的判断是通过加数据头和数据尾,校验和来判断接收到一个完整的数据包
dirdirdir3 2005-04-19
  • 打赏
  • 举报
回复
最好前面再加个开始字符串,如"start"等,后面加crc校验就万无一失了。
dirdirdir3 2005-04-19
  • 打赏
  • 举报
回复
可以先约定发送一个数据的大小啊,比如说1024000,然后就接受数据,收到多少就减去多少,等到接受到1024000个字符就完成了。
leojay 2005-04-19
  • 打赏
  • 举报
回复
谢谢楼上。

缓存设为0是用来做什么的?有什么效果呢?
加载更多回复(3)

18,363

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧