网络传输中send与recv需要注意的地方----------来自博客讨论
2015-06-18 19:46
519 查看
数据用send发出去后,recv一次应该接收多少?怎么知道接收完成了? [问题点数:20分,结帖人BeerGates]
不显示删除回复显示所有回复显示星级回复显示得分回复
只显示楼主
收藏
BeerGates BeerGates 本版等级: 结帖率:94.03% | 楼主发表于: 2008-08-03 08:52:10 send了一个1024K的东西出去,recv一次接收多少呢?当recv返回什么的时候才表示接收完成? 更多0分享到: 相关主题推荐: 数据 相关帖子推荐: 点击input获取全国各地的省市区 Oracle数据统计,麻烦大神帮我写几个sql语句 应该是向量问题。。。 导入数据数显乱码 Sql server 数据库设计的问题 sql语句执行效率低 求大神优化 php运行结果:Array ( ) Linq查询单张表数据时,怎样查出他关联的表的数据 准备好了么? 跳吧 !更多职位尽在 CSDN JOB 数据抓取工程师(JAVA,Python) 广州酷旅旅行社有限公司 | 6-12K/月 我要跳槽 大数据开发高级工程师(日志监控及ELK方向) 上海安畅网络科技股份有限公司 | 15-25K/月 我要跳槽 数据仓库工程师 北京盛华合创科技有限公司 | 15-25K/月 我要跳槽 数据挖掘开发工程师 精硕世纪科技(北京)有限公司 | 15-25K/月 我要跳槽 |
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理 回复次数:21 |
hhyttppd hhyttppd 本版等级: | #1 得分:0回复于: 2008-08-03 09:35:21 1.recv一次接收多少 看recv的返回值(0完成,<0 出错) 2.recv返回什么表示接收完成。 int recv( SOCKET s, char FAR* buf, int len, int flags ); If no error occurs, this function returns the number of bytes received. If the connection has been gracefully closed, the return value is zero. |
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理 |
arong1234 arong1234 本版等级: | #2 得分:2回复于: 2008-08-03 09:36:49 发送方发送前应该先发送一个长度信息,否则对方不可能知道自己该接收多少 至于接收缓冲大小,如果你发送的所有消息有最大长度,则设置为最大长度(超过1460字节就不要超过1460,因为报文一般都小于这个数,如果超过,会分成两个报文)我一般设计成1024字节或者2048字节 |
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理 |
BeerGates BeerGates 本版等级: | #3 得分:0回复于: 2008-08-03 13:18:43 引用 1 楼 hhyttppd 的回复: 1.recv一次接收多少 看recv的返回值(0完成, <0 出错) 2.recv返回什么表示接收完成。 int recv( SOCKET s, char FAR* buf, int len, int flags ); If no error occurs, this function returns the number of bytes received. If the connection has been gracefully closed, the return value is zero. 可是我怎么也得不到小于0的值呢?咋回事啊。 |
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理 |
BeerGates BeerGates 本版等级: | #4 得分:0回复于: 2008-08-03 13:22:17 引用 2 楼 arong1234 的回复: 发送方发送前应该先发送一个长度信息,否则对方不可能知道自己该接收多少 至于接收缓冲大小,如果你发送的所有消息有最大长度,则设置为最大长度(超过1460字节就不要超过1460,因为报文一般都小于这个数,如果超过,会分成两个报文)我一般设计成1024字节或者2048字节 先发送一个长度?这样吗? send一次可以发多少的?我看书没介绍一次可以发多少数据? |
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理 |
arong1234 arong1234 本版等级: | #5 得分:2回复于: 2008-08-03 13:32:38 不要发大报文是个基本原则,我一般控制在1024左右,<1460一般比较好,但是其实没有啥规定,只是自己这么做而已 |
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理 |
BeerGates BeerGates 本版等级: | #6 得分:0回复于: 2008-08-03 13:35:55 这样的啊?不知道大小限制如何?不知道有没有规定啊? 1024。 如果不知道大小,怎么才能接收完呢? |
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理 |
WinEggDrop WinEggDrop 本版等级: | #7 得分:2回复于: 2008-08-03 14:12:04 有多少就接多少呀.如果不出现什么错误,肯定接完的. |
对我有用[1] 丢个板砖[0] 引用 | 举报 | 管理 |
BeerGates BeerGates 本版等级: | #8 得分:0回复于: 2008-08-03 17:30:43 人家发,我不知道吧?recv有没有这个功能,知道已经把发送来的接收完了吗? |
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理 |
WinEggDrop WinEggDrop 本版等级: | #9 得分:0回复于: 2008-08-03 19:22:25 引用 8 楼 BeerGates 的回复: 人家发,我不知道吧?recv有没有这个功能,知道已经把发送来的接收完了吗? 如果你是阻塞的socket,那你不断调用recv()就是,接到对方发完将socket断开;如果是异步等的socket,有数据要接收你就能收到消息或信号,然后调用recv()接数据,直到收完对方断开socket就是. |
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理 |
hxfjb hxfjb 本版等级: | #10 得分:2回复于: 2008-08-03 21:37:39 tcp连接,你要自己定义一个发送和接收的协议; 1 你要知道你准备接收多少字节的数据,即是否接收了足够的数据可以进行处理了。 2 如果还没有接收足够的数据就断了(接收错误),那就断了,走人就行了。 |
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理 |
halve halve 本版等级: | #11 得分:2回复于: 2008-08-04 11:43:39 引用 5 楼 arong1234 的回复: 不要发大报文是个基本原则,我一般控制在1024左右, <1460一般比较好,但是其实没有啥规定,只是自己这么做而已 其实我一直都有楼主这样的问题... 另外问问, 为什么不要发大报文是基本原则, 之前不是说一次发送大数据(例如 16 * 1024)比多次分发小数据(1024)好么? 如果说, 要把 数据/报文 的传输分开处理, 从而增加系统的复杂性, 没有 >>>足够的好处<<<, 我觉得还不如统一用大缓冲(16 * 1024)处理来的实际? 想听听你的高见 ;) |
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理 |
hhyttppd hhyttppd 本版等级: | #12 得分:2回复于: 2008-08-04 17:22:56 《1460byte是只是个经验性规则,限制在单数据包不被分帧的情况下传输。 在大数据量的情况下,一次传很方便,我觉得也没什么不好的。 在socket per transport情况下,视对方友好关闭为传输结束(recv 返回0). 对于由自己设计的传输协议,一般采用这样的包格式(tcp之上): struct Packet_Header{ ushort uSize; ushort uPaketId; //可有可无,包格式编号 DWORD pData; }; 据具体的包格式,解析pData的数据。 因为,每次传输只需要取回前两个节做为传输长度即可验证数据是否完整。 |
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理 |
ok1234567 ok1234567 本版等级: | #13 得分:0回复于: 2008-08-05 09:46:07 可靠的方法 1、先发出一个传送数据的头结构,其中包含数据长度,接受端至少接受头结构的长度,然后决定后面的动作 2、有一个不会产生冲突的结束标记,比如HTTP头,就是由两对回车换行表示 任何数据传送前,先发送一个头结构,比较可靠,如果数据量不算太大,且不会产生编码混淆,可以定义一个结束标记 |
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理 |
cwb0525 草帽 本版等级: | #14 得分:2回复于: 2008-08-06 21:54:12 在socket per transport情况下,视对方友好关闭为传输结束(recv 返回0). 对于由自己设计的传输协议,一般采用这样的包格式(tcp之上): struct Packet_Header{ ushort uSize; ushort uPaketId; //可有可无,包格式编号 DWORD pData; }; 就是这样,顶12楼~! |
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理 |
BeerGates BeerGates 本版等级: | #15 得分:0回复于: 2008-08-07 02:58:00 我试了一下,服务这边一发送成功的话。立即关闭,客户端就判断recv返回0了。立即不接收数据了。 |
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理 |
zgc7622 zgc7622 本版等级: | #16 得分:2回复于: 2008-08-07 16:58:32 使用TCP协议发送数据的时候,最好在数据的前面带上本次发送的数据长度,这样方便另一方的粘包处理。 |
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理 |
orbit 吹泡泡的小猫 本版等级: | #17 得分:2回复于: 2008-08-07 17:20:16 用select判断一下有没有数据可收,有就收,没有就等待,不需要确切知道要接收的数据大小 |
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理 |
arvid_gs arvid_gs 本版等级: | #18 得分:2回复于: 2008-08-07 19:26:02 可以用多种模型来实现,最简单得就是用select模型来实现了,接受端要实现解析组包的功能,因为多久收完依赖于网络环境,有可能1024需要分多次收完,所以必须做分析组包的功能,比如连续发很3个包,我们收到的时候可能是3或5次,这样必须解析组合成实际发送的包 |
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理 |
yyunffu yyunffu 本版等级: | #19 得分:0回复于: 2008-08-08 08:42:44 在异步模式下,如果数据接收完毕,select会一直等待到超时发生,实际上这个超时有两种情况,或者数据收完超时,或者网络状况原因超时,这个是无法判断是否完整接收到数据的。 所以还是应该有个明确的数据长度比较好。数据接收完成就断开,出错再重新请求,直到获取完整数据。 |
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理 |
BeerGates BeerGates 本版等级: | #20 得分:0回复于: 2008-08-08 17:07:18 异步和Select模型有什么不同呢? |
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理 |
nuaa_maliang nuaa_maliang 本版等级: | #21 得分:0回复于: 2008-08-28 20:02:40 Send的太大或者太小都是不好的,超过1460的话,加上以太网的首部,超过MTU了,就会发生分片,不停的发太小的报文,导致糊涂窗口而且效率也很低。 Recv是本身是没有办法知道有没有收完的,TCP是一个无消息边界的流协议,SCTP才是有消息边界的,TCP只能告诉你这次收到了多少字节。 |
相关文章推荐
- linux中手工编译安装httpd服务全操作过程
- Java servlet example - HttpServletRequest, getPathInfo, and getRequestURI
- 第十六章:网络IPC:套接字
- android WebView 与 HttpClient Cookie
- TCP/IP滑动窗口
- TCP/IP滑动窗口
- TCP/IP滑动窗口
- 为 HTTP/2 头压缩专门设计的 HPACK
- Node.js学习--基础知识(9)--HTTP服务器
- 关于域中计算机调取网络共享目录中图片的问题
- http://linux.linuxidc.com/
- Spring MVC过滤器-HiddenHttpMethodFilter
- 简单HTTP服务器的Java实现
- http,tcp,udp,tcp/ip ,socket之间的关系
- 工业串口和网络软件通讯平台(SuperIO 2.0)发布
- Android_网络应用详解
- Android开发:如何实现TCP和UDP传输
- Cacti获取服务器TCP并发连接数
- 对比iOS网络组件:AFNetworking VS ASIHTTPRequest
- iscsi网络存储