永发信息网

linux网络编程中阻塞和非阻塞socket的区别

答案:3  悬赏:60  手机版
解决时间 2021-04-01 04:41
linux网络编程中阻塞和非阻塞socket的区别
最佳答案
阻塞socket和非阻塞socket的区别:
  1、读操作
  对于阻塞的socket,当socket的接收缓冲区中没有数据时,read调用会一直阻塞住,直到有数据到来才返回。当socket缓冲区中的数据量小于期望读取的数据量时,返回实际读取的字节数。当sockt的接收缓冲区中的数据大于期望读取的字节数时,读取期望读取的字节数,返回实际读取的长度。
  对于非阻塞socket而言,socket的接收缓冲区中有没有数据,read调用都会立刻返回。接收缓冲区中有数据时,与阻塞socket有数据的情况是一样的,如果接收缓冲区中没有数据,则返回错误号为EWOULDBLOCK,表示该操作本来应该阻塞的,但是由于本socket为非阻塞的socket,因此立刻返回,遇到这样的情况,可以在下次接着去尝试读取。如果返回值是其它负值,则表明读取错误。
  因此,非阻塞的rea调用一般这样写:
  if ((nread = read(sock_fd, buffer, len)) < 0)
{
if (errno == EWOULDBLOCK)
{
return 0; //表示没有读到数据
}else return -1; //表示读取失败
}else return nread;读到数据长度
  2、写操作
  对于写操作write,原理是类似的,非阻塞socket在发送缓冲区没有空间时会直接返回错误号EWOULDBLOCK,表示没有空间可写数据,如果错误号是别的值,则表明发送失败。如果发送缓冲区中有足够空间或者是不足以拷贝所有待发送数据的空间的话,则拷贝前面N个能够容纳的数据,返回实际拷贝的字节数。
  而对于阻塞Socket而言,如果发送缓冲区没有空间或者空间不足的话,write操作会直接阻塞住,如果有足够空间,则拷贝所有数据到发送缓冲区,然后返回.
  非阻塞的write操作一般写法是:
  int write_pos = 0;
int nLeft = nLen;
  while (nLeft > 0)
{
int nWrite = 0;
if ((nWrite = write(sock_fd, data + write_pos, nLeft)) <= 0)
{
if (errno == EWOULDBLOCK)
{
nWrite = 0;
}else return -1; //表示写失败
}
nLeft -= nWrite;
write_pos += nWrite;
}
return nLen;
  3、建立连接
  阻塞方式下,connect首先发送SYN请求道服务器,当客户端收到服务器返回的SYN的确认时,则connect返回.否则的话一直阻塞.
  非阻塞方式,connect将启用TCP协议的三次握手,但是connect函数并不等待连接建立好才返回,而是立即返回。返回的错误码为EINPROGRESS,表示正在进行某种过程.
  4、接收连接
  对于阻塞方式的倾听socket,accept在连接队列中没有建立好的连接时将阻塞,直到有可用的连接,才返回。
  非阻塞倾听socket,在有没有连接时都立即返回,没有连接时,返回的错误码为EWOULDBLOCK,表示本来应该阻塞。
  无阻塞的设置方法
  方法一:fcntl
int flag;
if (flag = fcntl(fd, F_GETFL, 0) <0) perror("get flag");
flag |= O_NONBLOCK;
if (fcntl(fd, F_SETFL, flag) < 0)
perror("set flag");
  方法二:ioctl
  int b_on = 1;
ioctl (fd, FIONBIO, &b_on);
全部回答
通俗一点,阻塞就是干不完不准回来,   
非阻塞就是你先干,我现看看有其他事没有,完了告诉我一声

您好,很高兴为您解答。


读操作
对于阻塞的socket,当socket的接收缓冲区中没有数据时,read调用会一直阻塞住,直到有数据到来才返回。当socket缓冲区中的数据量小于期望读取的数据量时,返回实际读取的字节数。当sockt的接收缓冲区中的数据大于期望读取的字节数时,读取期望读取的字节数,返回实际读取的长度。


对于非阻塞socket而言,socket的接收缓冲区中有没有数据,read调用都会立刻返回。接收缓冲区中有数据时,与阻塞socket有数据的情况是一样的,如果接收缓冲区中没有数据,则返回错误号为EWOULDBLOCK,表示该操作本来应该阻塞的,但是由于本socket为非阻塞的socket,因此立刻返回,遇到这样的情况,可以在下次接着去尝试读取。如果返回值是其它负值,则表明读取错误。


因此,非阻塞的rea调用一般这样写:if ((nread = read(sock_fd, buffer, len)) < 0)
{
if (errno == EWOULDBLOCK)
{
return 0; //表示没有读到数据
}else return -1; //表示读取失败
}else return nread;读到数据长度

写操作
对于写操作write,原理是类似的,非阻塞socket在发送缓冲区没有空间时会直接返回错误号EWOULDBLOCK,表示没有空间可写数据,如果错误号是别的值,则表明发送失败。如果发送缓冲区中有足够空间或者是不足以拷贝所有待发送数据的空间的话,则拷贝前面N个能够容纳的数据,返回实际拷贝的字节数。


而对于阻塞Socket而言,如果发送缓冲区没有空间或者空间不足的话,write操作会直接阻塞住,如果有足够空间,则拷贝所有数据到发送缓冲区,然后返回.


非阻塞的write操作一般写法是:int write_pos = 0;
int nLeft = nLen;
while (nLeft > 0)
{
int nWrite = 0;
if ((nWrite = write(sock_fd, data + write_pos, nLeft)) <= 0)
{
if (errno == EWOULDBLOCK)
{
nWrite = 0;
}else return -1; //表示写失败
}
nLeft -= nWrite;
write_pos += nWrite;
}
return nLen;
建立连接
阻塞方式下,connect首先发送SYN请求道服务器,当客户端收到服务器返回的SYN的确认时,则connect返回.否则的话一直阻塞.


非阻塞方式,connect将启用TCP协议的三次握手,但是connect函数并不等待连接建立好才返回,而是立即返回。返回的错误码为EINPROGRESS,表示正在进行某种过程.接收连接


对于阻塞方式的倾听socket,accept在连接队列中没有建立好的连接时将阻塞,直到有可用的连接,才返回。


非阻塞倾听socket,在有没有连接时都立即返回,没有连接时,返回的错误码为EWOULDBLOCK表示本来应该阻塞。

无阻塞的设置方法
方法一:fcntl
int flag;if (flag = fcntl(fd, F_GETFL, 0) <0) perror("get flag");flag |= O_NONBLOCK;if (fcntl(fd, F_SETFL, flag) < 0)perror("set flag");
方法二:ioctl
int b_on = 1;ioctl (fd, FIONBIO, &b_on);


方法二:ioctl
int b_on = 1;
ioctl (fd, FIONBIO, &b_on);


如若满意,请点击右侧【采纳答案】,如若还有问题,请点击【追问】



希望我的回答对您有所帮助,望采纳!


                                                                                                                             ~ O(∩_∩)O~
我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
大型高一座位号是39,40是连坐吗
好勒是什么意思
请和塑料袋说拜拜作文4o0字
当今我国创业形势怎样
上海护理院哪家不错?
谁说个笑话让我笑,财富给他,我笑点很高
海参蒸着吃还是煮着吃好
王皓一届国乒队员是哪些?
买的牛蛋煮出来软软的,外面皮没破,但是里面
一个男生从来没有主动联系我,在我主动联系他
普桑冒蓝烟不缺机油不缺水温度起来快.是什么
《若能说爱你》最新txt全集下载
2012年4月26日20点35分出生,是女孩,本人姓
诛仙隐藏任务只想救碧瑶怎么翻圈圈
稳当和稳重的区别是什么
推荐资讯
黑豆红豆红枣红花生枸杞能不能煮在一起
河南省临颍县是贫困县吗
阅读是…仿句
饭厅宽2.1*长2.4米,适合放多少米的餐桌椅呢?
83-34=45
DIN C55 相当于国产什么材料
1996年一月31日四点四十出生的女孩命运如何
求萌b娘的高清图
QTP中一个页面出现多处相同的名称,然后QTP测
昨晚梦到自己带AK47和98k,穿越到古代帮一个
谁敢收了它 Fendi x beats pro全球限量
预应力锚索施工完成后仍渗水怎样处理
正方形一边上任一点到这个正方形两条对角线的
阴历怎么看 ?