网络,socket

网络宏观结构

网络宏观结构

网络协议

网络协议ppt

基于windows的socket

基于windows TCP

加深理解

int PASCAL FAR recv (
                     _In_ SOCKET s,	//socket
                     _Out_writes_bytes_to_(len, return) __out_data_source(NETWORK) char FAR * buf, //接手数据的缓冲buff
                     _In_ int len, //想要接收的长度
                     _In_ int flags);	//标志位,一般NULL(接收数据后会从socket移除);MSG_PEEK(不移除socket的数据)

返回值:

  1. 大于0的值,表示recv成功,返回的是实际接受的字节数。
  2. 等于0的值,这个一般表示连接被关闭了。
  3. 小于0的值,这个一般就是SOCKET_ERROR了,值=-1;表示出错了。出错的话,可以用WSAGetLastError来获取详细的错误代码。

有几种常见的错误代码:

  1. 10038:在一个非套接字上尝试了一个操作。这个错误在多线程的时候容易出现。做socket的时候,前后之间最好加入错误的判断。
  2. 10057:这个错误,表示套接字没有连接。有时候connect之后没有判断,直接调用recv就有可能出现这种错误。
  3. 10014:这个表示指针非法了。使用之前把缓冲区分配好就可以了,现在一般很少出现内存不足的情况。还有就是要注意len的大小,如果len太大的话,会导致缓冲区溢出。要是你用这个在你的电脑上开一个端口,轻者导致程序崩溃,重者被别人拿到和程序一样高的权限。

细节描述:
当应用程序调用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


int PASCAL FAR select (
                        _In_ int nfds, //一个文件描述符集合保存在fd_set变量中,可读,可写,异常这三个描述符集合需要使用三个变量来保存,分别是 readfds,writefds,exceptfds
                        _Inout_opt_ fd_set FAR *readfds, //监视文件描述符的一个集合,我们监视其中的文件描述符是不是可读,或者更准确的说,读取是不是不阻塞了
                        _Inout_opt_ fd_set FAR *writefds, //监视文件描述符的一个集合,我们监视其中的文件描述符是不是可写,或者更准确的说,写入是不是不阻塞了
                        _Inout_opt_ fd_set FAR *exceptfds, //用来监视发生错误异常文件
                        _In_opt_  const struct timeval FAR *timeout); //timeout表示select返回之前的时间上限(即超时)

原理:
理解select模型的关键在于理解fd_set,为说明方便,取fd_set长度为1字节,fd_set中的每一bit可以对应一个文件描述符fd。则1字节长的fd_set最大可以对应8个fd。
​ 执行fd_set set;FD_ZERO(&set);则set用位表示是0000,0000。
​ 若fd=5,执行FD_SET(fd,&set);后set变为0001,0000(第5位置为1)
​ 若再加入fd=2,fd=1,则set变为0001,0011
​ 执行select(6,&set,0,0,0)阻塞等待
​ 若fd=1,fd=2上都发生可读事件,则select返回,此时set变为0000,0011。注意:没有事件发生的fd=5被清空。
若fd=1上都发生可读事件,则select返回,此时set变为0000,0001。注意:没有事件发生的fd=1,fd=5被清空。

返回值:
成功时:返回描述符集合中”准备好了“的文件描述符数量。
超时:返回0
错误:返回-1,并设置 errno

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值