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

linux socket 阻塞

Linux中的Socket阻塞是指在进行网络通信时,当一个进程调用Socket接口进行读写操作时,若该操作无法立即完成,则该进程会被挂起,直到操作完成为止。这种行为称为阻塞模式。

基础概念

Socket: 是网络通信的基本构建块,它允许不同计算机上的应用程序通过互联网进行通信。

阻塞模式: 当进程调用Socket接口进行读写操作时,如果数据没有准备好(对于读操作)或缓冲区已满(对于写操作),则该调用会阻塞,直到数据准备好或缓冲区有空间为止。

优势

  1. 简单易用: 阻塞模式编程模型相对简单,容易理解和实现。
  2. 资源占用少: 在阻塞模式下,进程在等待IO操作完成时不会占用CPU资源。

类型

  • 读阻塞: 当调用recv()read()时,如果没有数据可读,进程会被阻塞。
  • 写阻塞: 当调用send()write()时,如果发送缓冲区已满,进程会被阻塞。
  • 连接阻塞: 当调用connect()时,如果连接不能立即建立,进程会被阻塞。

应用场景

  • 传统的客户端-服务器模型: 在这种模型中,服务器通常在一个循环中等待客户端的连接请求,然后处理这些请求。
  • 简单的数据传输应用: 对于不需要高并发处理能力的应用,阻塞模式可以满足需求。

遇到的问题及原因

问题: 程序在等待Socket操作时变得无响应。 原因: 可能是由于网络延迟、对方未发送数据或发送速度慢等原因导致Socket操作无法立即完成。

解决方法

  1. 设置超时: 使用setsockopt()函数为Socket操作设置超时时间,避免无限期等待。
  2. 设置超时: 使用setsockopt()函数为Socket操作设置超时时间,避免无限期等待。
  3. 使用非阻塞模式: 将Socket设置为非阻塞模式,这样即使操作不能立即完成也不会阻塞进程。
  4. 使用非阻塞模式: 将Socket设置为非阻塞模式,这样即使操作不能立即完成也不会阻塞进程。
  5. 多线程/多进程处理: 使用多个线程或进程来处理并发连接,每个线程/进程处理一个或多个连接。
  6. 异步IO: 利用select(), poll(), 或epoll()等机制进行异步IO操作,这些机制允许单个进程/线程管理多个Socket连接。

示例代码(非阻塞模式)

代码语言:txt
复制
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>

int main() {
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock < 0) {
        perror("socket");
        return 1;
    }

    int flags = fcntl(sock, F_GETFL, 0);
    fcntl(sock, F_SETFL, flags | O_NONBLOCK);

    struct sockaddr_in server_addr;
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(8080);
    server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");

    if (connect(sock, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
        if (errno != EINPROGRESS) {
            perror("connect");
            close(sock);
            return 1;
        }
    }

    // 进行其他非阻塞操作...

    close(sock);
    return 0;
}

通过上述方法,可以有效解决Linux Socket阻塞带来的问题,提高程序的响应性和稳定性。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

从linux源码看socket的阻塞和非阻塞 顶

从linux源码看socket的阻塞和非阻塞 笔者一直觉得如果能知道从应用到框架再到操作系统的每一处代码,是一件Exciting的事情。 大部分高性能网络框架采用的是非阻塞模式。...笔者这次就从linux源码的角度来阐述socket阻塞(block)和非阻塞(non_block)的区别。 本文源码均来自采用Linux-2.6.24内核版本。...一个TCP非阻塞client端简单的例子 如果我们要产生一个非阻塞的socket,在C语言中如下代码所示: // 创建socket int sock_fd = socket(AF_INET, SOCK_STREAM...的阻塞\非阻塞状态 我们用fcntl修改socket的阻塞\非阻塞状态。...阻塞后什么时候恢复运行呢 情况1:有对应的网络数据到来 首先我们看下网络分组到来的内核路径,网卡发起中断后调用netif_rx将事件挂入CPU的等待队列,并唤起软中断(soft_irq),再通过linux

3.6K20
  • linux网络编程系列(七)--如何将socket设置成非阻塞的,非阻塞socket与阻塞的socket在收发数据上的区别

    生成socket时设置 socket函数创建socket默认是阻塞的,也可以增加选项将socket设置为非阻塞的: int s = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK...使用fcntl设置 将socket设置为非阻塞的 if ((nFlags = fcntl (nSock, F_GETFL, 0)) < 0) return 0; nFlags = nFlags...| O_NONBLOCK; if (fcntl (nSock, F_SETFL, nFlags) < 0) return 0; 将socket设置为阻塞的 if ((nFlags =...非阻塞和阻塞在收发数据时有什么区别 3.1 发送时的区别 3.1.1 TCP发送(即send函数) send函数在阻塞模式下,会等待所有数据都被拷贝到发送缓冲区才会返回,也就是说,阻塞模式下,send函数返回值必定是参数中发送长度的大小...3.2 接收时的区别 3.2.1 TCP接收(即recv函数) 在阻塞模式下, recv将会阻塞,直到缓冲区里有至少一个字节才返回,当没有数据到来时,recv会一直阻塞或者直到超时,不会返回; 在非阻塞模式下

    3.4K30

    ioctlsocket() 用法 socket recvfrom 阻塞 非阻塞 设置

    iMode);//非阻塞设置 rs=recvfrom(socketc,rbuf,sizeof(rbuf),0,(SOCKADDR*)&addr,&len); int ioctlsocket (SOCKET...不知道大家有没有遇到过这种情况,当socket进行TCP连接的时候(也就是调用connect时),一旦网络不通,或者是ip地址无效,就可能使整个线程阻塞。一般为30秒(我测的是20秒)。...readfds指定一個Socket数组(应该是一个,但这里主要是表现为一个Socket数组),select检查该数组中的所有Socket。...writefds指定一个Socket数组,select检查该数组中的所有Socket。如果成功返回,则writefds中存放的是符合‘可写性’条件的数组成员(如连接成功)。...exceptfds指定一个Socket数组,select检查该数组中的所有Socket。如果成功返回,则cxceptfds中存放的是符合‘有异常’条件的数组成员(如连接接失败)。

    3.8K20

    Linux下Socket编程(三)——非阻塞select的使用简介

    简介 什么叫阻塞和非阻塞 select fd_set类型的变量相关宏定义 fcntl 实例 select总是返回1的问题。...什么叫阻塞和非阻塞 阻塞方式block,顾名思义,就是进程或是线程执行到这些函数时必须等待某个事件的发生,如果事件没有发生,进程或线程就被阻塞,函数不能立即返回。...使用Select就可以完成非阻塞(所谓非阻塞方式non- block,就是进程或线程执行此函数时不必非要等待事件的发生,一旦执行肯定返回,以返回值的不同来反映函数的执行情况,如果事件发生则与阻塞方式相同...SELECT_fncl.png 示例 客户端创建socket 调用fcntl设置阻塞模式 调用connect开始连接。...(方便读写) 关闭socket select总是返回1的问题。

    4.3K10

    socket阻塞与非阻塞,同步与异步、IO模型

    阻塞IO和非阻塞IO的区别就在于:应用程序的调用是否立即返回! 同步和异步都只针对于本机SOCKET而言的。同步和异步,阻塞和非阻塞,有些混用,其实它们完全不是一回事,而且它们修饰的对象也不相同。...二、Linux下的五种I/O模型: 1)阻塞I/O(blocking I/O) 2)非阻塞I/O (nonblocking I/O) 3) I/O复用(select 和poll) (I/O multiplexing...我们把一个SOCKET接口设置为非阻塞就是告诉内核,当所请求的I/O操作无法完成时,不要将进程睡眠,而是返回一个错误。...当使用socket()函数和WSASocket()函数创建套接字时,默认都是阻塞的。在创建套接字之后,通过调用ioctlsocket()函数,将该套接字设置为非阻塞模式。...Linux下的函数是:fcntl()。 套接字设置为非阻塞模式后,在调用Windows Sockets API函数时,调用函数会立即返回。

    3.1K30

    socket阻塞与非阻塞,同步与异步、IO模型

    阻塞IO和非阻塞IO的区别就在于:应用程序的调用是否立即返回! 同步和异步都只针对于本机SOCKET而言的。...Linux下的五种I/O模型 1)阻塞I/O(blocking I/O) 2)非阻塞I/O (nonblocking I/O) 3) I/O复用(select 和poll) (I/O multiplexing...当使用socket()函数和WSASocket()函数创建套接字时,默认的套接字都是阻塞的。...Linux下的函数是:fcntl(). 套接字设置为非阻塞模式后,在调用Windows Sockets API函数时,调用函数会立即返回。...在现在的Linux内核里有都能够支持,其中epoll是Linux所特有,而select则应该是POSIX所规定,一般操作系统均有实现 select: select本质上是通过设置或者检查存放fd标志位的数据结构来进行下一步处理

    2.2K20

    socket阻塞与非阻塞,同步与异步IO模型

    Linux下的五种I/O模型 1)阻塞I/O(blocking I/O) 2)非阻塞I/O (nonblocking I/O) 3) I/O复用(select 和poll) (I/O multiplexing...当使用socket()函数和WSASocket()函数创建套接字时,默认的套接字都是阻塞的。...我们把一个SOCKET接口设置为非阻塞就是告诉内核,当所请求的I/O操作无法完成时,不要将进程睡眠,而是返回一个错误。...Linux下的函数是:fcntl().     套接字设置为非阻塞模式后,在调用Windows Sockets API函数时,调用函数会立即返回。...在现在的Linux内核里有都能够支持,其中epoll是Linux所特有,而select则应该是POSIX所规定,一般操作系统均有实现 select: select本质上是通过设置或者检查存放fd标志位的数据结构来进行下一步处理

    3.4K10

    php 纯socket编程核心的东西!socket_read阻塞的问题!

    fileno 的本质:可读写文件 一图了解 socket原理 Python 标准输入输出 通常:一些简单的概念结合在一起就变得混乱 重点: 1、阻塞就是,没有按照PHP的思维习惯,在莫名其妙的请款下就停止了...【阻塞】,阻塞的本质是在底层操作系统、网络接口等用c语言封装后暴露出来的一个PHP函数(看c的socket总结出来的) 2、socket_accept、socket_read、socket_recv默认都会阻塞...== false){//PHP_NORMAL_READ 不够length就阻塞,PHP_BINARY_READ不会 // var_dump($buf_read_data."...($socket_accept); // //socket_read、socket_recv、socket_accept三个默认都是阻塞的,不阻塞就是:不会'卡死'在这些函数上 //不开启不能反向写入数据...和client的socket是同一个socket,客户端的socket sleep几秒,这里也sleep几秒。

    2.2K20

    Linux编程(阻塞和非阻塞IO)

    Linux设备驱动中的阻塞和非阻塞I/0,简单来说就是对I/O操作的两种不同的方式,驱动程序可以灵活的支持用户空间对设备的这两种访问方式。...非阻塞应用程序通常使用select系统调用查询是否可以对设备进行无阻塞的访问最终会引发设备驱动中 poll 函数执行。...=1); //串口上没有输入则返回,所以循环读取 printf("%c/n",buf); 阻塞操作常常用等待队列来实现,而非阻塞操作用轮询的方式来实现。...null); } } } 下面说说设备驱动中的poll()函数,函数原型如下: static unsigned int poll(struct file *file, struct socket...,写访问的掩码 驱动函数中的poll()函数典型模板如下: static unsigned int xxx_poll(struct file *filp,struct socket *sock,poll_table

    5.5K20

    从Java Socket非阻塞到Netty入门流程

    本博客 猫叔的博客,转载请申明出处 阅读本文约 “4分钟” 适读人群:同学 Java IO,Socket非阻塞通信流程 这里我们使用一个内嵌的永久循环,来让Socket成为一个非阻塞的通信流程...如上图所示,ServerSocket是我们自建的一个类,通过启动线程,且线程内置一个真循环,防止accept阻塞; 在客户端监听类上,将监听到的socket作为参数,传递到客户端监听类上,并再次启动线程...,获取一个InputStream,同时再次在这个刚刚启动线程内置一个真循环,为的是不断获取信息并回写; 这里要注意的是,第一个真循环是保证获取新连接不会阻塞,第二个真循环是保证不停的获取客户端信息并回写...NioEventLoop(事件循环) 1、新连接接入 2、连接上的数据读取 Channel(抽象连接) Socket、SocektChannel(IO\NIO)抽象 ChannelHandler(业务逻辑处理

    62220

    linux阻塞与非阻塞(connect连接超时)

    非阻塞connect详情介绍可以参见文章:https://blog.csdn.net/qq_41453285/article/details/89890429 一、非阻塞connect概述 man手册...,进一步来等待非阻塞connect客户端与服务端建立完整地连接,在等待的过程中,如果非阻塞connect建立成功了,客户端的sock_fd就会变成可写的(这个在本人的IO复用文章中介绍过,见下图) ④当非阻塞...connect建立成功之后还可以利用getsockopt来读取错误码并清除该socket上的错误: 如果错误码为0,表示连接成功建立 否则连接失败 二、非阻塞connect的移植性问题 移植性问题如下...: 1.首先,非阻塞的socket可能导致connect始终失败 2.其次,select对处于EINPROGRESS状态下的socket可能不起作用 3.最后,对于出错的socket,getsockopt...在有些系统(比如Linux)上返回-1,而在有些系统上(比如源自伯克利的UNIX)返回0 这些问题没有一个统一的解决办法 三、编码演示案例 #include #include <stdlib.h

    6.5K10

    使用epoll时需要将socket设为非阻塞吗?

    接下来使用 select 和 poll 函数去判断 socket 是否可写即可,当然,Linux 系统上还需要额外加一步——使用 getsockopt 函数判断此时 socket 是否有错误,这就是所谓的异步...282 4.1 学习网络编程时应该掌握的socket函数 282 4.1.1 在Linux上查看socket函数的帮助信息 283 4.1.2 在Windows上查看socket函数的帮助信息 285...上的select函数 302 4.5.2 Windows上的select函数 317 4.6 socket的阻塞模式和非阻塞模式 318 4.6.1 如何将socket设置为非阻塞模式 318 4.6.2...send和recv函数在阻塞和非阻塞模式下的表现 320 4.6.3 非阻塞模式下send和recv函数的返回值总结 331 4.6.4 阻塞与非阻塞socket的各自适用场景 333 4.7 发送0...4.10.1 分析 346 4.10.2 注意事项 350 4.11 Linux EINTR错误码 351 4.12 Linux SIGPIPE信号 352 4.13 Linux poll 函数的用法

    2.4K10

    (四) 如何将socket设置为非阻塞模式

    1. windows平台上无论利用socket()函数还是WSASocket()函数创建的socket都是阻塞模式的: SOCKET WSAAPI socket( _In_ int af,...另外,windows和linux平台上accept()函数返回的socekt也是阻塞的,linux另外提供了一个accept4()函数,可以直接将返回的socket设置为非阻塞模式: int accept...除了创建socket时,将socket设置成非阻塞模式,还可以通过以下API函数来设置: linux平台上可以调用fcntl()或者ioctl()函数,实例如下: fcntl(sockfd, F_SETFL.../details/44306993),linux下如果调用fcntl()设置socket为非阻塞模式,不仅要设置O_NONBLOCK模式,还需要在接收和发送数据时,需要使用MSG_DONTWAIT标志,...再次调用ioctlsocket()将该socket设置成阻塞模式才会成功。因为调用WSAAsyncSelect()或WSAEventSelect()函数会自动将socket设置成非阻塞模式。

    4.6K70

    【Linux】深入 Linux 进程等待机制:阻塞与非阻塞的奥秘

    如果任意时刻调用wait/waitpid,子进程存在且正常运行,则可能阻塞。 如果不存在该进程,则立即出错放回。...sleep(5); exit(257); } else { //father int status = 0; pid_t ret = waitpid(-1,&status,0);//阻塞等待...{ //father int status = 0; pid_t ret = 0; do { ret = waitpid(-1,&status,WNOHANG);//非阻塞等待...3.解释堵塞与非堵塞 阻塞场景:打电话等朋友接听 你拨打朋友的电话,直到朋友接通之前你什么都做不了。这就像阻塞调用,你必须等着事情完成。...非阻塞场景:发消息等待回复 你给朋友发了个消息,等他们回你。你不用一直盯着手机看,而是可以去做别的事情,等收到消息后再查看。这就像非阻塞调用,你不需要等着完成才能做其他事情。

    13210

    【Linux】:Socket编程 TCP

    函数原型(C/C++) 在 POSIX 系统(如 Linux)中,listen 函数的原型如下: int listen(int sockfd, int backlog); 在 Windows 系统中,listen...函数原型(C/C++) 在 POSIX 系统(如 Linux)中,accept 函数的原型如下: int accept(int sockfd, struct sockaddr *addr, socklen_t...EchoServer -- 多进程 上面我们写的只是单进程方面的,接下来我们来创建多进程方面的 但是这里有个问题:当前创建出子进程的时候,父进程还需等待子进程,默认这里就阻塞了 但是我们这里是让子进程去做文本处理...,如果子进程不退出/不返回,那么父进程不依然阻塞在这里嘛 阻塞之后还是无法accept,这不还是单进程嘛,但是我们还是必须得 wait,因为不 wait ,子进程一推出就会有僵尸问题 此时就需要用到 信号...EchoServer -- 线程池 引入我们之前写的【Linux】:线程库 Thread.hpp 简单封装 Thread.hpp 以及 单例模式下的【Linux】:日志策略 + 线程池(单例模式 Threadpool.hpp

    8810
    领券