【计算机网络】网络编程中的阻塞和非阻塞

 🔥博客主页: 我要成为C++领域大神

🎥系列专栏【C++核心编程】 【计算机网络】 【Linux编程】 【操作系统】

❤️感谢大家点赞👍收藏⭐评论✍️

本博客致力于分享知识,欢迎大家共同学习和交流。

网络编程中有两种模式:阻塞和非阻塞,默认是采用阻塞方式。

什么是阻塞和非阻塞

阻塞和非阻塞是对操作请求者在等待返回结果时的状态描述,阻塞时,在操作请求结果返回前,当前线程会被挂起,得到结果之后返回;非阻塞时,如果不能立刻得到结果,系统不会挂起当前线程,而是直接返回错误信息,因此对应非阻塞的情况,调用者需要定时轮询查看处理状态。
阻塞状态下,不占用CPU;非阻塞状态下,一直占用CPU。
举个例子:

老王烧水,把水壶放在炉子上,就在旁边等着水开---阻塞:不占用CPU,第一时间知道等待的事情发生了

老王烧水,把水壶放在炉子上,就去客厅看电视了,每隔一段时间回来看看水开了没---非阻塞:一直占用CPU,等待事情发生的时候并不能第一时间知道

在我们前面编写的UDP通信中,SOCKET默认是阻塞,ioctlsock函数可以设置为非阻塞
从官方帮助文档可以看出,第三个参数非0时,可以设置状态为非阻塞。

int WSAAPI ioctlsocket(
  [in]      SOCKET s,
  [in]      long   cmd,
  [in, out] u_long *argp
);
//-------------------------
// Set the socket I/O mode: In this case FIONBIO
// enables or disables the blocking mode for the 
// socket based on the numerical value of iMode.
// If iMode = 0, blocking is enabled; 
// If iMode != 0, non-blocking mode is enabled.
 //socket默认是阻塞的,设置socket为非阻塞模式
 u_long iMode=FIONBIO;
 ioctlsocket(sock, FIONBIO, &iMode);

当将socket设置为非阻塞后,程序不会卡在recvfrom了,函数会立即返回,并返回10035(调用失败)错误代码。

缓冲区(buffer)

缓冲区是内存空间的一部分。也就是说,在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输入或输出的数据,这部分预留的空间就叫做缓冲区。缓冲区根据其对应的是输入设备还是输出设备,分为输入缓冲区和输出缓冲区。

创建socket时,在内核空间创建发送缓冲区和接收缓冲区

调用recvfrom函数的时候是从接收缓冲区中把数据拷贝到应用程序的空间
调用sendto函数的时候就是把数据拷贝到发送缓冲区中

 int nRecvSize = 0;
 int nSendSize = 0;
 int size = sizeof(nRecvSize);
 getsockopt(sock,SOL_SOCKET,SO_RCVBUF,(char*)&nRecvSize,&size);
 getsockopt(sock,SOL_SOCKET,SO_SNDBUF,(char*)&nSendSize,&size);
 cout << "nRecvSize:" << nRecvSize << "  nSendSize:" << nSendSize << endl;
 //65536字节 操作系统分配的接收和发送缓冲区大小为64k

发送的阻塞和非阻塞:

当发送缓冲区空间剩余不够大时,阻塞发送就是等待空间足够大以后,再往发送缓冲区中拷贝数据

当发送缓冲区空间剩余不够大时,非阻塞发送就是有多少空间就往里拷贝多少数据,剩余数据由应用程序自己处理

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值