宝塔服务器面板,一键全能部署及管理,送你10850元礼包,点我领取

recv函数原型: intrecv(sockets,char *buf,int len,int flags )功能:使用recv函数从通过TCP连接的另一端接收数据。 参数1 :指定接收套接字描述符; 指示存储参数recv函数接收的数据的缓冲区。 参数3 :表示buf长度的参数4 :通常为0。

同步套接字recv函数的执行流程:当APP应用程序调用recv函数时,recv首先等待s的发送缓冲器中的数据通过协议进行传输,如果协议在传输s的发送缓冲器中的数据时发生网络错误,则为recv 如果s的发送缓冲区中没有数据,或者在通过协议成功发送数据之后,recv首先检查套接字s的接收缓冲区,并且如果s的接收缓冲区中没有数据,或者如果协议正在接收数据,则recv将对协议进行解码协议接收完数据后,recv函数将s的接收缓冲区的数据复制到buf。 (因为协议接收到的数据有可能比buf的长度大,所以要注意在这种情况下要调用recv函数几次将s的接收缓冲区的数据复制完毕。 recv函数只是一个拷贝数据(真正的接收数据通过协议进行),recv函数返回实际拷贝的字节数; 如果在复制期间recv出错,则返回SOCKET_ERROR; 如果网络在等待协议接收数据时中断,recv函数将返回0。

读取数据时需要考虑的一点是,如果recv ()返回的大小等于请求的大小,则很可能意味着缓冲区中的数据还没有读完,并且该事件还未处理,因此必须重新读取。 while(RS ) buflen=recv(activeevents(I ).data.FD if(buflen0)//由于处于非阻塞模式,如果buflen为EAGAIN,则当前缓冲区无法读取数据else return; }elseif(buflen==0) ) /此处表示对方套接字已成功关闭。 ) if ) buflen!=sizeof(buf ) ) rs=0; else rs=1; //需要重新读取}

recv函数只是一个拷贝数据(真正的接收数据是通过协议实现的),recv函数返回实际拷贝的字节数。 如果在复制期间recv出错,则返回SOCKET_ERROR; 如果网络在等待协议接收数据时中断,recv函数将返回0。 缺省套接字不区分未阻塞和未阻塞recv返回值,且都在0错误=0连接关闭0时接收数据大小。 特别是,如果返回值为0,且(errno==eintr|||errno==ewouldblock|| errno==e again ),则认为连接正常。但是,在块模式中,recv接收到的数据

从TCP协议的角度来看,建立的TCP连接有两种关闭方法。 一种是普通关闭,也就是4挥手关闭连接。 另一种是异常关闭,通常称为连接重置(RESET )。

首先,对通常关闭时的4次挥手的状态转移进行说明,关闭连接的主动侧的状态转移为fin _ wait _1- fin _ wait _2- time _ wait,关闭连接的对方侧的状态转移为close ACK包由协议栈自动执行,但FIN包必须由APP应用层主动通过closesocket或shutdown发送。 通常,在连接成功关闭后,recv将获得返回值0,send将获得错误代码10058。

除此之外,在我们的日常APP中,连接也经常异常关闭。 例如,如果APP应用程序被强制关闭、本地网络突然中断、网卡失效或网线被拔出,连接就会重置。 重置连接会生成RST包,同时网络缓冲区中未接收(发送)的数据会丢失。 重置连接时,本站的send或recv为错误代码10053(closesocket时为10038 ),对方的recv为错误代码10054,send为错误代码10053 ) closesocket时为10055

操作系统提供了两个函数: closesocket和shutdown。 通常,closesocket会向对方发送FIN包,但也有例外。 例如,如果一个工作线程通过调用recv接收数据,则从外部调用closesocket将重置连接,同时向另一方发送RST包。 这个RST数据包是自己自发生成的。

shutdown可用于关闭指定方向的连接。 此函数接受套接字和关闭方向两个参数,可能的值为SD_SEND、SD_RECEIVE和SD_BOTH。 如果方向为SD_SEND,则无论套接字处于什么状态(recv阻塞或空闲),都会向对方发送FIN包。 请注意这一点和closesocket的区别。 此时,我方进入FIN_WAIT_2状态,对方进入CLOSE_

WAIT状态,本方依然可以调用recv接收数据;方向取值为SD_RECEIVE时,双发连接状态没有改变,依然处于ESTABLISHED状态,本方依然可以send数据,但是,如果对方再调用send方法,连接会被立即重置,同时向对方发送一个RST包,这个RST包是被动产生的,这点注意与closesocket的区别。
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的发送缓冲中没有数据或者数据被协议成功发送完毕后,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信号,进程对该信号的默认处理是进程终止。