如何让recvfrom函数函数有点脾气

温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!&&|&&
LOFTER精选
网易考拉推荐
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
阅读(25037)|
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
历史上的今天
loftPermalink:'',
id:'fks_',
blogTitle:'recv函数的用法详解',
blogAbstract:'recv函数
int recv( SOCKET s,&&&& char FAR *buf,&&&&& int len,&&&& int flags&&&& );&&&
不论是客户还是服务器应用程序都用recv函数从TCP连接的另一端接收数据。
该函数的第一个参数指定接收端套接字描述符;
第二个参数指明一个缓冲区,该缓冲区用来存放recv函数接收到的数据;
第三个参数指明buf的长度;
第四个参数一般置0。
这里只描述同步Socket的recv函数的执行流程。当应用程序调用recv函数时,recv先等待s的发送缓冲中的数据被协议传送完毕,如果协议在传送s的发送缓冲中的数据时出现网络错误,那么recv函数返回SOCKET_ERROR,如果s的发送缓冲中没有数',
blogTag:'',
blogUrl:'blog/static/1',
isPublished:1,
istop:false,
modifyTime:0,
publishTime:1,
permalink:'blog/static/1',
commentCount:0,
mainCommentCount:0,
recommendCount:1,
bsrk:-100,
publisherId:0,
recomBlogHome:false,
currentRecomBlog:false,
attachmentsFileIds:[],
groupInfo:{},
friendstatus:'none',
followstatus:'unFollow',
pubSucc:'',
visitorProvince:'',
visitorCity:'',
visitorNewUser:false,
postAddInfo:{},
mset:'000',
remindgoodnightblog:false,
isBlackVisitor:false,
isShowYodaoAd:false,
hostIntro:'',
hmcon:'0',
selfRecomBlogCount:'0',
lofter_single:''
{list a as x}
{if x.moveFrom=='wap'}
{elseif x.moveFrom=='iphone'}
{elseif x.moveFrom=='android'}
{elseif x.moveFrom=='mobile'}
${a.selfIntro|escape}{if great260}${suplement}{/if}
{list a as x}
推荐过这篇日志的人:
{list a as x}
{if !!b&&b.length>0}
他们还推荐了:
{list b as y}
转载记录:
{list d as x}
{list a as x}
{list a as x}
{list a as x}
{list a as x}
{if x_index>4}{break}{/if}
${fn2(x.publishTime,'yyyy-MM-dd HH:mm:ss')}
{list a as x}
{if !!(blogDetail.preBlogPermalink)}
{if !!(blogDetail.nextBlogPermalink)}
{list a as x}
{if defined('newslist')&&newslist.length>0}
{list newslist as x}
{if x_index>7}{break}{/if}
{list a as x}
{var first_option =}
{list x.voteDetailList as voteToOption}
{if voteToOption==1}
{if first_option==false},{/if}&&“${b[voteToOption_index]}”&&
{if (x.role!="-1") },“我是${c[x.role]}”&&{/if}
&&&&&&&&${fn1(x.voteTime)}
{if x.userName==''}{/if}
网易公司版权所有&&
{list x.l as y}
{if defined('wl')}
{list wl as x}{/list}2012年 总版技术专家分年内排行榜第一
2013年 总版技术专家分年内排行榜第七2011年 总版技术专家分年内排行榜第五2009年 总版技术专家分年内排行榜第九
2013年7月 Linux/Unix社区大版内专家分月排行榜第二2012年6月 Linux/Unix社区大版内专家分月排行榜第二2011年5月 Linux/Unix社区大版内专家分月排行榜第二2011年4月 Linux/Unix社区大版内专家分月排行榜第二2011年3月 Linux/Unix社区大版内专家分月排行榜第二2010年10月 Linux/Unix社区大版内专家分月排行榜第二2010年9月 Linux/Unix社区大版内专家分月排行榜第二
2011年9月 Linux/Unix社区大版内专家分月排行榜第三2010年12月 Linux/Unix社区大版内专家分月排行榜第三2010年11月 Linux/Unix社区大版内专家分月排行榜第三2010年9月 C/C++大版内专家分月排行榜第三
2013年 总版技术专家分年内排行榜第三
2012年 总版技术专家分年内排行榜第七
本帖子已过去太久远了,不再提供回复功能。有关send() / recv()函数的理解 - CSDN博客
有关send() / recv()函数的理解
 1.send 函数
  int send( SOCKET s, const char FAR *buf, int len, int flags );
  不论是客户还是服务器应用程序都用send函数来向TCP连接的另一端发送数据。客户程序一般用send函数向服务器发送请求,而服务器则通常用send函数来向客户程序发送应答。
  该函数的第一个参数指定发送端套接字描述符;
  第二个参数指明一个存放应用程序要发送数据的缓冲区;
  第三个参数指明实际要发送的数据的字节数;
  第四个参数一般置0。
  这里只描述同步Socket的send函数的执行流程。当调用该函数时,
  (1)send先比较待发送数据的长度len和套接字s的发送缓冲的长度, 如果len大于s的发送缓冲区的长度,该函数返回SOCKET_ERROR;
  (2)如果len小于或者等于s的发送缓冲区的长度,那么send先检查协议是否正在发送s的发送缓冲中的数据,如果是就等待协议把数据发送完,如果协议还没有开始发送s的发送缓冲中的数据或者s的发送缓冲中没有数据,那么send就比较s的发送缓冲区的剩余空间和len
  (3)如果len大于剩余空间大小,send就一直等待协议把s的发送缓冲中的数据发送完
  (4)如果len小于剩余 空间大小,send就仅仅把buf中的数据copy到剩余空间里(注意并不是send把s的发送缓冲中的数据传到连接的另一端的,而是协议传的,send仅仅是把buf中的数据copy到s的发送缓冲区的剩余空间里)。
  如果send函数copy数据成功,就返回实际copy的字节数,如果send在copy数据时出现错误,那么send就返回SOCKET_ERROR;如果send在等待协议传送数据时网络断开的话,那么send函数也返回SOCKET_ERROR。
  要注意send函数把buf中的数据成功copy到s的发送缓冲的剩余空间里后它就返回了,但是此时这些数据并不一定马上被传到连接的另一端。如 果协议在后续的传送过程中出现网络错误的话,那么下一个Socket函数就会返回SOCKET_ERROR。(每一个除send外的Socket函数在 执 行的最开始总要先等待套接字的发送缓冲中的数据被协议传送完毕才能继续,如果在等待时出现网络错误,那么该Socket函数就返 回 SOCKET_ERROR)
  注意:在Unix系统下,如果send在等待协议传送数据时网络断开的话,调用send的进程会接收到一个SIGPIPE信号,进程对该信号的默认处理是进程终止。
  通过测试发现,异步socket的send函数在网络刚刚断开时还能发送返回相应的字节数,同时使用select检测也是可写的,但是过几秒钟之后,再send就会出错了,返回-1。select也不能检测出可写了。
2. recv函数
  int recv( SOCKET s, char FAR *buf, int len, int flags);
   不论是客户还是服务器应用程序都用recv函数从TCP连接的另一端接收数据。该函数的第一个参数指定接收端套接字描述符;
  第二个参数指明一个缓冲区,该缓冲区用来存放recv函数接收到的数据;
  第三个参数指明buf的长度;
  第四个参数一般置0。
  这里只描述同步Socket的recv函数的执行流程。当应用程序调用recv函数时,
  (1)recv先等待s的发送缓冲中的数据被协议传送完毕,如果协议在传送s的发送缓冲中的数据时出现网络错误,那么recv函数返回SOCKET_ERROR,
  (2)如果s的发送缓冲中没有数据或者数据被协议成功发送完毕后,recv先检查套接字s的接收缓冲区,如果s接收缓冲区中没有数据或者协议正在接收数 据,那么recv就一直等待,直到协议把数据接收完毕。当协议把数据接收完毕,recv函数就把s的接收缓冲中的数据copy到buf中(注意协议接收到的数据可能大于buf的长度,所以 在这种情况下要调用几次recv函数才能把s的接收缓冲中的数据copy完。recv函数仅仅是copy数据,真正的接收数据是协议来完成的),
  recv函数返回其实际copy的字节数。如果recv在copy时出错,那么它返回SOCKET_ERROR;如果recv函数在等待协议接收数据时网络中断了,那么它返回0。
  注意:在Unix系统下,如果recv函数在等待协议接收数据时网络断开了,那么调用recv的进程会接收到一个SIGPIPE信号,进程对该信号的默认处理是进程终止。如果你通过printf想在某个点打印信息,但是怎么运行都打印不出,那可能就是服务器或客户端send/recv失败,直接终止进程了。可以设置忽略这个信号:
signal(SIGPIPE, SIG_IGN);
本文已收录于以下专栏:
相关文章推荐
首先要理解的是,缓冲区有两种。第一种是用户定义的缓冲区,就是send里的缓冲区参数。另一种就是套接字缓冲区,是由协议自定的。可以用getsockopt获取其大小,并用setsockopt重置其大小。发...
/aixingfou/archive//2120956.html
int send( SOCKET s,      con...
int send( SOCKET s,      const char FAR *buf,      int len,      int flags ...
Tcp协议本身是可靠的,并不等于应用程序用tcp发送数据就一定是可靠的.不管是否阻塞,send发送的大小,并不代表对端recv到多少的数据.
在阻塞模式下, send函数的过程是将应用程序请求发...
send函数工作原理:
  send函数只负责将数据提交给协议层。 当调用该函数时,send先比较待发送数据的长度len和套接字s的发送缓冲区的长度,如果len大于s的发送缓冲区的长度,该函数返...
send函数工作原理:
     send函数只负责将数据提交给协议层。 当调用该函数时,send先比较待发送数据的长度len和套接字s的发送缓冲区的长度,如果len大于s的发送缓冲区的长度,该函数返...
int send( SOCKET s,    const char FAR *buf,    int len,    int flags );  
不论是客户还是服务器应用...
read、write
头文件: #include
原型:size_t read ( int fd, void *buf, size_t count); 
            s...
他的最新文章
讲师:宋宝华
讲师:何宇健
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)新手园地& & & 硬件问题Linux系统管理Linux网络问题Linux环境编程Linux桌面系统国产LinuxBSD& & & BSD文档中心AIX& & & 新手入门& & & AIX文档中心& & & 资源下载& & & Power高级应用& & & IBM存储AS400Solaris& & & Solaris文档中心HP-UX& & & HP文档中心SCO UNIX& & & SCO文档中心互操作专区IRIXTru64 UNIXMac OS X门户网站运维集群和高可用服务器应用监控和防护虚拟化技术架构设计行业应用和管理服务器及硬件技术& & & 服务器资源下载云计算& & & 云计算文档中心& & & 云计算业界& & & 云计算资源下载存储备份& & & 存储文档中心& & & 存储业界& & & 存储资源下载& & & Symantec技术交流区安全技术网络技术& & & 网络技术文档中心C/C++& & & GUI编程& & & Functional编程内核源码& & & 内核问题移动开发& & & 移动开发技术资料ShellPerlJava& & & Java文档中心PHP& & & php文档中心Python& & & Python文档中心RubyCPU与编译器嵌入式开发驱动开发Web开发VoIP开发技术MySQL& & & MySQL文档中心SybaseOraclePostgreSQLDB2Informix数据仓库与数据挖掘NoSQL技术IT业界新闻与评论IT职业生涯& & & 猎头招聘IT图书与评论& & & CU技术图书大系& & & Linux书友会二手交易下载共享Linux文档专区IT培训与认证& & & 培训交流& & & 认证培训清茶斋投资理财运动地带快乐数码摄影& & & 摄影器材& & & 摄影比赛专区IT爱车族旅游天下站务交流版主会议室博客SNS站务交流区CU活动专区& & & Power活动专区& & & 拍卖交流区频道交流区
丰衣足食, 积分 766, 距离下一级还需 234 积分
论坛徽章:0
10可用积分
看了一下资料,recv返回0好像是客户端断开连接的意思,
但是我抓了别人的程序的通迅包,
发现客户端发了一个0字节的包到服务器,紧接着又发送了一串字符串到服务器,然后他们还在进行通讯.
难道服务器接到0字节的数据的时候,没有当客户端断开连接进行处理?
服务端接收到0字节的时候,应该怎样处理呢?
楼主有个基本概念的错误. 对于TCP, 传输0字节数据的报文是正常的, 比如窗口探测报文, 纯ACK报文等. recv是用户user/TCP层面的调用, 而网络传输是TCP/lower network层面的行为. 网络传输了0字节数据的报文, 和recv到0字节的数据是两个完全无关的概念.
&&nbsp|&&nbsp&&nbsp|&&nbsp&&nbsp|&&nbsp&&nbsp|&&nbsp
小富即安, 积分 2163, 距离下一级还需 2837 积分
论坛徽章:0
楼主有个基本概念的错误. 对于TCP, 传输0字节数据的报文是正常的, 比如窗口探测报文, 纯ACK报文等. recv是用户user/TCP层面的调用, 而网络传输是TCP/lower network层面的行为. 网络传输了0字节数据的报文, 和recv到0字节的数据是两个完全无关的概念.
稍有积蓄, 积分 413, 距离下一级还需 87 积分
论坛徽章:0
recv返回0是因为收到了FIN分节,所以返回0,表示对方主动关闭连接
至于抓包,0字节的包是什么样子的呢?
丰衣足食, 积分 766, 距离下一级还需 234 积分
论坛徽章:0
那个是minisniffer,没有这个包细节的.
意思是说服务器接收到0字节的包也要具体对待吗?
白手起家, 积分 41, 距离下一级还需 159 积分
论坛徽章:0
发现客户端发了一个0字节的包到服务器
你怎么看到的?
可能是tcp协议上用到的包,比如心跳包,连接 断开包.
丰衣足食, 积分 653, 距离下一级还需 347 积分
论坛徽章:0
0字节表示连接断开
白手起家, 积分 0, 距离下一级还需 200 积分
论坛徽章:0
说的非常好.
TCP STREAM 给用户的数据流和TCP协议里面的包是两回事. 后者包括有数据长度是0的包---用户层看不到,抓包可以看到.
原帖由 ideawu 于
17:51 发表
楼主有个基本概念的错误. 对于TCP, 传输0字节数据的报文是正常的, 比如窗口探测报文, 纯ACK报文等. recv是用户user/TCP层面的调用, 而网络传输是TCP/lower network层面的行为. 网络传输了0字节数据的报文, 和re ...
丰衣足食, 积分 766, 距离下一级还需 234 积分
论坛徽章:0
是啊,我对网络程序还不是很了解,但急于解决一个问题。
粗略浏览了一下unix网络编程,
好像没说到这个问题。
哪该怎样处理呢?
有什么好的例子吗?
[ 本帖最后由 prettywolf 于
20:47 编辑 ]
白手起家, 积分 13, 距离下一级还需 187 积分
论坛徽章:0
客户端的程序 recv返回0,说明服务器主动断开了连接,需要重新连一下服务器.
服务器端的程序recv返回0,说明客户端主动断开了连接,当作断线处理一下就可以了.
小富即安, 积分 3250, 距离下一级还需 1750 积分
论坛徽章:0
en&&这个问题比较细致了。
其实象lz 这样的sniffer 还是会有一个问题的。 重传。 我可以将一个数据包连续传3次。 或者故意
将2个数据包 颠倒顺序传。&&简单的sniffer 都是会出问题的。
北京盛拓优讯信息技术有限公司. 版权所有 京ICP备号 北京市公安局海淀分局网监中心备案编号:22
广播电视节目制作经营许可证(京) 字第1234号
中国互联网协会会员&&联系我们:
感谢所有关心和支持过ChinaUnix的朋友们
转载本站内容请注明原作者名及出处

我要回帖

更多关于 socket recv函数 的文章

 

随机推荐