首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

尝试从套接字读取,但它阻塞了while循环

从套接字读取数据时,如果使用阻塞式的读取方式,可能会导致while循环被阻塞。阻塞式读取是指当没有数据可读时,读取操作会一直等待直到有数据可读为止。这种情况下,while循环无法继续执行其他操作,造成程序的停滞。

为了解决这个问题,可以采用非阻塞式读取方式。非阻塞式读取是指当没有数据可读时,读取操作会立即返回一个错误码或空值,而不会等待。通过使用非阻塞式读取,可以在没有数据可读时立即执行其他操作,提高程序的并发性和响应性。

在实际开发中,可以使用以下方法来实现非阻塞式读取:

  1. 使用select或poll函数:这些函数可以监视多个套接字,当其中任意一个套接字有数据可读时,就会返回。通过使用这些函数,可以在while循环中不断检查套接字是否有数据可读,从而避免阻塞。
  2. 使用多线程或多进程:可以将读取操作放在一个独立的线程或进程中进行,这样while循环就不会被阻塞。通过线程或进程间的通信机制,可以将读取到的数据传递给主线程或进程进行处理。
  3. 使用非阻塞式IO函数:一些编程语言或框架提供了非阻塞式的IO函数,可以直接使用这些函数进行非阻塞式读取。例如,在Python中可以使用socket.setblocking(False)将套接字设置为非阻塞模式,然后使用socket.recv()函数进行读取。

总结起来,为了避免while循环被阻塞,可以采用非阻塞式读取方式,如使用select/poll函数、多线程/多进程或非阻塞式IO函数。这样可以提高程序的并发性和响应性,确保在没有数据可读时也能继续执行其他操作。

腾讯云相关产品和产品介绍链接地址:

  • 腾讯云云服务器(CVM):提供弹性计算能力,满足各类业务需求。产品介绍链接
  • 腾讯云云数据库MySQL版:提供高性能、可扩展的MySQL数据库服务。产品介绍链接
  • 腾讯云容器服务:提供高性能、高可靠的容器化应用部署和管理服务。产品介绍链接
  • 腾讯云人工智能平台:提供丰富的人工智能服务和工具,帮助开发者构建智能化应用。产品介绍链接
  • 腾讯云物联网套件:提供全面的物联网解决方案,支持设备连接、数据采集、设备管理等功能。产品介绍链接
  • 腾讯云移动应用分析:提供全面的移动应用数据分析服务,帮助开发者了解用户行为和应用性能。产品介绍链接
  • 腾讯云对象存储(COS):提供安全、稳定、低成本的云端存储服务,适用于各类数据存储需求。产品介绍链接
  • 腾讯云区块链服务:提供高性能、可扩展的区块链服务,支持快速搭建和管理区块链网络。产品介绍链接
  • 腾讯云虚拟专用网络(VPC):提供安全可靠的网络隔离环境,帮助用户构建私有网络。产品介绍链接
  • 腾讯云安全组:提供网络访问控制和安全防护,保障云服务器的网络安全。产品介绍链接
  • 腾讯云音视频处理:提供高效、稳定的音视频处理服务,支持转码、截图、水印等功能。产品介绍链接
页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

最全服务器模型详解——单线程阻塞到多线程非阻塞

应用程序遍历套接的事件检测 当多个客户端向服务器请求时,服务器端会保存一个套接连接列表中,应用层线程对套接列表轮询尝试读取或写入。...对于读取操作,如果成功读取到若干数据,则对读取到的数据进行处理;如果读取失败,则下一个循环再继续尝试。对于写入操作,先尝试将数据写入指定的某个套接,写入失败则下一个循环再继续尝试。...这样看来,不管有多少个套接连接,它们都可以被一个线程管理,一个线程负责遍历这些套接列表,不断地尝试读取或写入数据。这很好地利用了阻塞的时间,处理能力得到提升。...内核遍历套接的事件检测 这种方式将套接的遍历工作交给操作系统内核,把对套接遍历的结果组织成一系列的事件列表并返回应用层处理。...这样就避免了遍历套接的操作,但仍然有大量无用的数据(状态为0的元素)内核复制到应用层中。于是就有第二种事件检测方式。 内核基于回调的事件检测方式二如图所示。服务器端有多个客户端套接连接。

2.7K50

庖丁解牛:NIO核心概念与机制详解 06 _ 连网和异步 IO

另一方面,异步 I/O 调用不会阻塞。相反,你将注册对特定 I/O 事件的兴趣 ― 可读的数据的到达、新的套接连接,等等,而在发生这样的事件时,系统将会告诉你。...第二行将 ServerSocketChannel 设置为 非阻塞的 。我们必须对每一个要使用的套接通道调用这个方法,否则异步 I/O 就不能工作。...删除处理过的 SelectionKey 在处理 SelectionKey 之后,我们几乎可以返回主循环。但是我们必须首先将处理过的 SelectionKey 选定的键集合中删除。...我们调用迭代器的 remove() 方法来删除处理过的 SelectionKey: it.remove(); 现在我们可以返回主循环并接受从一个套接中传入的数据(或者一个传入的 I/O 事件)。...在本例中,由于这是一个 echo server,我们只希望套接读取数据并马上将它发送回去。

14230

如何在Python中使用Linux epoll

C10K问题讨论用于处理多个并发套接的一些替代方法,例如异步套接的使用。 这些套接在某些事件发生之前不会阻塞。 而是,程序在异步套接上执行一个操作,并立即通知该操作成功还是失败。...第13行:由于默认情况下套接阻塞的,因此使用非阻塞(异步)模式是必需的。 第15行:创建一个epoll对象。 第16行:对服务器套接上的读取事件感兴趣。...第23行:如果套接服务器上发生读取事件,则可能已经创建了新的套接连接。 第25行:将新套接设置为非阻塞模式。 第26行:对新套接读取(EPOLLIN)事件感兴趣。...第39行:发送完完整的响应后,请停止对进一步的读取或写入事件感兴趣。 第40行:如果显式关闭连接,则套接关闭是可选的。此示例程序使用它来使客户端首先关闭。...在示例4中,第25、36和45行引入了循环,直到发生异常为止(否则,其他所有数据将被处理)。第32、38和48行捕获预期的套接异常。

3.2K10

并发服务器(三):事件驱动

阻塞式 I/O 更好理解,因为这是我们使用 I/O 相关 API 时的“标准”方式。套接接收数据的时候,调用 函数会发生阻塞,直到它从端口上接收到了来自另一端套接的数据。...这里就实现使用非阻塞的 让监听者检查套接变为可能,并且在没有数据的时候重新获得控制权。换句话说,用编程的语言说这就是轮询polling—— 主程序周期性的查询套接以便读取数据。...首先,让我们谈谈主循环。它看起来是什么样的呢?先让我们想象一下服务器有一堆任务,它应该监视哪些东西呢?两种类型的套接活动: 新客户端尝试连接。这些客户端应该被 。 已连接的客户端发送数据。...这个结构体告诉主循环,是否应该监视套接读取事件、写入事件,或者两者都监视。上述代码展示 和 是怎么在合适的描述符集合中被调用的。...轮询需要一直发生,而 实际上会阻塞到有一个或多个套接准备好读取/写入; 会比一直询问浪费少得多的 CPU 时间。

1.6K50

高性能网络通信框架Netty-Java NIO基础

3.1 客户端程序 这个客户端功能是当客户端连接到服务端后,给服务器发送一个Hello,然后套接里面读取服务器端返回的内容并打印,具体代码如下: public class NioClient {...代码(6)(7)调用套接通道的connect方法,连接服务器(服务器套接地址为127.0.0.1:7001),由于步骤(3)设置为非阻塞,所以步骤(6)马上会返回。...然后进入while循环进行事件处理,其中代码(8)选择已经就绪的网络IO事件,如果当前没有就绪的则阻塞当前线程。当有就绪事件后,会返回获取的事件个数,会执行代码(9)具体取出来具体事件列表。...代码(10.4)则看如果当前事件key是OP_READ事件,说明服务器发来的数据已经在接受buffer就绪,客户端可以去具体拿出来了,然后代码10.4.1客户端套接里面读取数据并打印。...注:设置套接为非阻塞后,connect方法会马上返回的,所以需要根据结果判断是否为链接建立OK,如果没有成功,则需要设置对该套接的op_connect事件感兴趣,在这个事件到来的时候还需要调用finishConnect

58020

linux网络编程之socket(九):使用select函数改进客户端服务器端程序

出现上述问题的根本原因在于客户端程序不能并发处理标准输入读取数据和套接读取数据两个事件,我们可以使用前面讲过的select函数来完善客户端程序,如下所示: void do_echocli(int ...循环中,如果select返回说明有事件发生,依次判断是哪些事件发生,如果是标准输入有数据可读,则读取后再次回到循环开头select阻塞等待事件发生,如果是套接口有数据可读,且返回为0则说明对方已经关闭连接...程序第一次进入while 循环,只把监听套接加入关心的事件,select返回说明监听套接有可读事件,即已完成连接队列不为空,这时调用accept不会阻塞,返回一个已连接套接,将这个套接加入allset...,因为第一次运行则nready = 1,直接continue跳回到while 循环开头,再次调用select,这次会关心监听套接和一个已连接套接的可读事件,如果继续有客户端连接上来则继续将其加入allset...服务完毕再次回到while 开头调用select 阻塞时,就关心一个监听套接和2个已连接套接的可读事件,一直循环下去。

3.7K00

【Netty】NIO 选择器 ( Selector ) 通道 ( Channel ) 缓冲区 ( Buffer ) 网络通信案例

NIO 通信 服务器端 流程说明 ---- NIO 网络通信 服务器端 操作流程 , 与 BIO 原理类似 , 基本流程是 启动服务器套接通道 , 创建选择器 , 将服务器套接通道注册给选择器 ,...监听客户端连接事件 , 客户端连接成功后 , 创建套接通道 , 将新创建的通道注册给选择器 , 然后监听该通道的读取事件 ; 启动 -> 创建选择器 -> 创建服务器通道 -> 注册服务器通道 ->...: 并设置该通道网络通信模式为非阻塞模式 serverSocketChannel.configureBlocking(false) , 注意这里设置阻塞模式 , 其 对应的客户端套接通道 SocketChannel...判定事件触发 : //阻塞监听, 查看是否有事件触发, 如果有就在下面处理 //如果没有 continue 终止循环, 继续下一次循环...创建套接通道 : 调用 SocketChannel.open() 方法 , 即可获取套接通道 ( SocketChannel ) , 之后将该通道设置为 非阻塞通信模式 socketChannel.configureBlocking

66220

Java NIO之套接通道

与文件通道不同,套接通道可以运行在非阻塞模式下。...如果在连接未建立起来的情况下,管道中读取,或向管道写入数据,会触发 NotYetConnectedException 异常。所以要进行循环检测,以保证连接完成建立。...非阻塞模式虽然不会阻塞线程,但是在方法返回后,还要进行循环检测,线程实际上还是被阻塞。...紧接着进入 while 循环,然后就可以和服务端愉快的聊天。 上面的代码和叙述都没啥意思,最后我们还是来看看上面代码的运行效果,一图胜前言。...[u5j97apr0c.gif] 4.总结 到这里,关于套接通道的相关内容就讲完了,不知道大家有没有看懂。本文仅从使用的角度分析套接通道的用法,至于套接通道的实现,这并不是本文关注的重点。

1.1K60

【Netty】NIO 网络编程 聊天室案例

) , 注册给选择器 ; 服务器端的消息转发流程 : 服务器端收到客户端发送的消息 , 将该消息转发给除该客户端外的其它客户端 , 选择器中可以获取到所有的 通道 , 注意 屏蔽 服务器套接通道...服务器套接通道 : 调用 open 静态方法创建服务器套接通道 , 并绑定 8888 端口 , 设置非阻塞网络通信模式 ; // 创建并配置 服务器套接通道 ServerSocketChannel...服务器端选择器 : 调用 open 静态方法获取 选择器 , 注册之前创建的 服务器套接通道 ; // 获取选择器, 并注册 服务器套接通道 ServerSocketChannel selector...处理客户端消息转发事件 : ① 读取客户端上传的数据 : 通过 SelectionKey 获取 通道 和 缓冲区 , 使用 套接通道 ( SocketChannel ) 读取 缓冲区 ( ByteBuffer...连接服务器 : 连接服务器 , 并设置网络通信非阻塞模式 ; // 创建并配置 服务器套接通道 ServerSocketChannel socketChannel = SocketChannel.open

1.3K10

网络编程基础第四讲阻塞模型

这个就是我们常说的阻塞. 只要我们创建的套接都是阻塞模型. 就是说数据接受不到不返回. 我们可以设置为非阻塞.就是不管数据有没有来到都会返回.如果来到.会有通知.我们可以编程接受数据....设置非阻塞模式方法   ioctlsocket(SOCKET s, long cmd, u_long *arpg); 改变套接字模式.为飞租she....阻塞迭代模式步骤   1.生成一个函数.绑定本地地址跟监听.   2.生成一个函数.专门接受一个客户端连接.并且返回对应连接的套接.   3.处理没一个客户端的连接.实现接受跟发送数据.   4.关闭一个连接....绑定地址,开始监听 SOCKET BindAnListen(int nBacklog) { //创建套接 BOOL bRet = FALSE; SOCKET hSocket...INVALID_SOCKET == hSocket) { DebugLog(TEXT("main Bind Fail")); goto Opt; } // 2.循环接受套接连接

33820

从零开始手写Tomcat的教程4节---Tomcat默认连接器

,将 avaiable 设为 false 重新进入阻塞,得到用户的返回用户的 socket,最后就能够通过 process 处理请求。...然后,有个 while 循环用来保持输入流中读取,直到 HttpProcessor 被停止,一个异常被抛出或者连接给关闭为止。 while (!...否则,shutdownInput 方法将会调用,而套接将被关闭. try { shutdownInput(input); socket.close(); shutdownInput 方法检查是否有未读取的字节...---- 解析连接 parseConnection 方法套接中获取到网络地址并把它赋予 HttpRequestImpl 对象。 它也检查是否使用代理并把套接赋予请求对象。...循环,可以持续读取 HTTP 请求直到再也没有更多的头部可以读取到。

82110

Python升级之路( Lv16 ) 网络编程

将string中的数据发送到连接的套接,但在返回之前会尝试发送所有数据....(flag)如果flag为0,则将套接设为非阻塞模式,否则将套接设为阻塞模式(默认值)....非阻塞模式下,如果调用recv()没有发现任何数据,或send()调用无法立即发送数据,那么将引起socket.error异常.s.makefile()创建一个与该套接相关连的文件 2....关闭连接 s.close() 按顺序分别启动服务端模块(接收数据) 和 客户端模块(发送数据) 运行结果 持续通信 核心: 利用While循环让程序持续挂起, 并且设置一个点让循环关闭 实操:...关闭连接 tcp.close() 按顺序分别启动服务端模块(接收数据) 和 客户端模块(发送数据) 运行结果 持续通信 核心: 利用While循环让程序持续挂起, 并且设置一个点让循环关闭 实操:

84620

一文读懂五大 IO 模型的前世今生( select、epoll、epoll)

IO 是将第一阶段的等待读就绪改为非阻塞,但是第二阶段的数据读取还是阻塞的,非阻塞 read 最重要的是提供我们在一个线程内管理多个文件描述符的能力。...这时我们自然而然就会想到把上述循环检测连接(文件描述符)可读的过程交给操作系统去做,从而避免频繁的进行系统调用。当然操作系统给我们提供这样的函数:select、poll、epoll。...new Tread(){ while(select(arr) > 0){ for(connfd : arr){ if(connfd can read){ // 如果套接可读...epoll 基于高效的红黑树结构,提供三个核心操作,主要流程如下所示:伪代码:listenfd = socket(); // 打开一个网络通信套接bind(listenfd); /...new Tread(){ while(arr = epoll_wait()){ for(connfd : arr){ // 仅返回可读套接 newTheadDeal

70430

Python Socket通信黏包问题分

[WinError 10013] 以一种访问权限不允许的方式做了一个访问套接尝试 原因:端口被占用导致 解决: Windows下 C:\> netstat -ano|findstr 8080...服务端套接函数 s.bind() 绑定(主机,端口号)到套接 s.listen() 开始TCP监听 s.accept() 被动接受TCP客户的连接,(阻塞式)等待连接的到来 客户端套接函数...s.getsockname() 当前套接的地址 s.getsockopt() 返回指定套接的参数 s.setsockopt() 设置指定套接的参数 s.close()...关闭套接 面向锁的套接方法 s.setblocking() 设置套接阻塞与非阻塞模式 s.settimeout() 设置阻塞套接操作的超时时间 s.gettimeout...() 得到阻塞套接操作的超时时间 面向文件的套接的函数 s.fileno() 套接的文件描述符 s.makefile() 创建一个与该套接相关的文件

52920

Python与套接

() 被动接受TCP客户的连接,(阻塞式)等待连接的到来 客户端套接函数 s.connect() s.connect_ex() s.connect_ex() connect()函数的扩展版本,出错时返回出错码...() 设置指定套接的参数 s.close() 关闭套接 面向锁的套接方法 s.setblocking() 设置套接阻塞与非阻塞模式 s.settimeout() 设置阻塞套接操作的超时时间...s.gettimeout() 得到阻塞套接操作的超时时间 面向文件的套接的函数 s.fileno() 套接的文件描述符 s.makefile() 创建一个与该套接相关的文件 第一版,单个客户端与服务端通信...read()/recv() 函数也是如此,也输入缓冲区中读取数据,而不是直接网络中读取。...,也可以readline,也可以for循环,但是读取出来的数据 大小就不固定,影响效率,有可能读的比较小,也可能很大,像视频文件一般都是一行的二进制字节 流。

2.4K30

Unix的IO模型解析

需要注意,实际读取的字节数可能小于数组的长度,方法的返回值正是实际读取的字节数。 非阻塞式IO 允许将一个套接设置为非阻塞。...其模型如下 可以看到,在内核没有数据时,尝试对数据的读取不会导致线程阻塞,而是快速的返回一个错误。直到内核中收到数据时,尝试读取,就会将数据内核复制到用户空间,进行操作。...IO复用 IO复用指的应用程序阻塞在系统提供的两个调用select或poll上。当应用程序关注的套接存在可读情况(也就是内核收到数据),select或poll的调用被返回。...一旦有数据,内核等待结束,select调用也就返回了。 信号驱动IO ? 与非阻塞IO类似,其在数据等待阶段并不阻塞,但是原理不同。信号驱动IO是在套接上注册一个信号调用方法。...异步IO 异步IO的实现一般是通过系统调用,向内核注册一个套接读取动作。这个调用一般包含了:缓存区指针,缓存区大小,偏移量、操作完成时的通知方式。

48530

C语言网络编程-tcp服务器实现

阻塞式TCP服务器 在c语言中,可以使用fcntl函数,将套接设置为非阻塞的 #include  #include //inet_addr() sockaddr_in...,无法读取返回-1                 continue;             }             if (str_length == 0)    //读取数据完毕关闭套接             ...,如果全部socket无法读取(没有事件变化),则相当于是while(1),会使cpu繁忙     } } 这样,我们就实现一个单进程多客户端的tcp服务器,不需要多进程也能实现多客户端,但是看最后一行注释能发现一个问题...:非阻塞下,会无限循环,让代码空转,这样浪费的性能也是巨大的,那我们该怎么完善呢?...accept直到没有数据可读, 由于必须一直循环读取,所以当accept没有数据可读时,必须是非阻塞模式,否则会阻塞 实现代码 #include  #include <arpa/inet.h

6K62
领券