最近在公司项目中突然报错如下 “connect: Interrupted system call”, 经过查找代码发现是在创建 socket 中执行了 connect 函数失败导致。上网查阅资料发现这是 信号中断EINTR 与 慢系统调用 的问题。

  慢系统调用:可能永远阻塞的系统调用

  EINTR说明:如果进程在一个慢系统调用(slow system call)中阻塞时,当捕获到某个信号且相应信号处理函数返回时,这个系统调用被中断,调用返回错误,设置errno为EINTR(相应的错误描述为“Interrupted system call”)。

  在博客 http://blog.csdn.net/benkaoya/article/details/17262053  信号中断 与 慢系统调用 有详细介绍。

  那么针对 EINTR 错误应该如何处理,或者如何规避这类问题。 建议查看此链接 http://www.madore.org/~david/computers/connect-intr.html

  以下给出一些常用的处理方法:

    ◆ 人为重启被中断的系统调用

    ◆ 安装信号时设置 SA_RESTART属性(该方法对有的系统调用无效)

    ◆  忽略信号(让系统不产生信号中断)

人为重启被中断的系统调用

  人为当碰到EINTR错误的时候,有一些可以重启的系统调用要进行重启,而对于有一些系统调用是不能够重启的。例如:accept、read、write、select、和open之类的函数来说,是可以进行重启的。不过对于套接字编程中的connect函数我们是不能重启的,若connect函数返回一个EINTR错误的时候,我们不能再次调用它,否则将立即返回一个错误。针对connect不能重启的处理方法是,必须调用select来等待连接完成。

  对于非 connect 函数可以尝试使用重新执行系统调用的方法。

  对于 connect 函数出现 EINTR 错误的时候,处理过程如下:

 int check_conn_is_ok(socket_t sock) {
struct pollfd fd;
int ret = ;
socklen_t len = ; fd.fd = sock;
fd.events = POLLOUT; while ( poll (&fd, , -) == - ) {
if( errno != EINTR ){
perror("poll");
return -;
}
} len = sizeof(ret);
if ( getsockopt (sock, SOL_SOCKET, SO_ERROR,
&ret,
&len) == - ) {
perror("getsockopt");
return -;
} if(ret != ) {
fprintf (stderr, "socket %d connect failed: %s\n",
sock, strerror (ret));
return -;
} return ;
}

  调用时如下:

if(connnect()) {
if(errno == EINTR) {
if(check_conn_is_ok() < ) {
perror();
return -;
}
else {
printf("connect is success!\n");
}
}
else {
perror("connect");
return -;
}
}

【网络编程】——connect函数遇见EINTR的处理的更多相关文章

  1. c/c++ 网络编程 getaddrinfo 函数

    网络编程 getaddrinfo 函数 解析网址,返回IP地址. 例子: #include <iostream> #include <string.h> #include &l ...

  2. c/c++ 网络编程 bind函数

    网络编程 bind函数 bind的作用是确定端口号. 正常处理都是先bind,然后listen 如果不bind,直接listen,会是什么结果? 内核会自动随机分配一个端口号 例子: #include ...

  3. socket中的函数遇见EINTR的处理【转】

    转自:http://blog.chinaunix.net/uid-21501855-id-4490453.html 这几天,写服务器代码过程当中,遇见EINRT信号的问题,我是借鉴 <unp & ...

  4. UNIX网络编程——select函数的并发限制和 poll 函数应用举例

    一.用select实现的并发服务器,能达到的并发数,受两方面限制 1.一个进程能打开的最大文件描述符限制.这可以通过调整内核参数.可以通过ulimit -n来调整或者使用setrlimit函数设置,  ...

  5. Linux网络编程-readn函数、writen函数、readline函数实现

    readn函数功能:在网络编程的读取数据中,通常会需要用到一个读指定字节才返回的函数,linux系统调用中没有给出,需要自己封装. readn实现代码: int readn(int fd, void ...

  6. 健壮的网络编程IO函数-RIO包

    RIO包 简介 Rio包即为Robust io函数包.包中函数是对Linux基本I/O函数的封装,使其更加健壮.高效,更适用于网络编程. 分析 Rio包由rio_t结构体和系列函数组成. 首先是两个不 ...

  7. 网络编程select函数

    select函数的作用: 在编程的过程中,经常会遇到许多阻塞的函数,好像read和网络编程时使用的recv, recvfrom函数都是阻塞的函数,当函数不能成功执行的时候,程序就会一直阻塞在这里,无法 ...

  8. linux c网络编程之函数

    1. struct protoent *protocol=getprotobyname(char *p); 功能:通过协议名获取协议类型信息 解释:p为字符串指针,指向一个协议名,如icmp,stru ...

  9. UNIX网络编程——fcntl函数

    fcntl函数提供了与网络编程相关的如下特性: 非阻塞式I/O.  通过使用F_SETFL命令设置O_NONBLOCK文件状态标志,我们可以把一个套接字设置为非阻塞型. 信号驱动式I/O. 通过使用F ...

随机推荐

  1. Mat 转 IplImage

    Mat 转 IplImage 分类: OpenCV2013-06-02 17:00 1487人阅读 评论(0) 收藏 举报 Mat 转 IplImage Mat image1; IplImage *i ...

  2. 使用PPT制作交叉密文图

    曾几何时,一张图火遍大江南北,互相流传. 其中的奥秘早已破解出来,但是仍乐趣无穷. 来回顾这样一张图吧! 最近,在朋友圈中,这样的一种图又流行起来,被改成不同的版本. 可是这样一种图片到底是怎样做出来 ...

  3. android firmware 利用UDP socket发送Magic Packet--c语言版本

    android firmware 利用UDP socket发送Magic Packet 1 Magic Packet格式: 6个0xFF + 16个Dst Mac Address 2 代码需要设置目的 ...

  4. ORACLE恢复神器之ODU/AUL/DUL

    分享ORACLE数据库恢复神器之ODU.DUL和AUL工具. ODU:ORACLE DATABASE UNLOADER DUL:DATA UNLOADER AUL:也称MyDUL 关于三种工具说明: ...

  5. ASP.NET MVC 下拉列表使用小结

    ASP.NET MVC中下拉列表的用法很简单,也很方便,具体来说,主要是页面上支持两种Html帮助类的方法:DropDownList()和DropDownListFor().这篇博文主要作为个人的一个 ...

  6. Spec模板

    Spec模板      一.概述   1.项目背景    图书馆在正常运营中面对大量书籍.读者信息以及两者间相互联系产生的借书信息.还书信息.现有的人工记录方法既效率低又错误过多,大大影响了图书馆   ...

  7. hibernate date类型插入数据库时精度只到日期没有时间

    由hibernate 的逆向工具从数据库表生成的*.hbm.xml ,对于数据库的date类型生成如下:        <property name = "crttime"  ...

  8. .Net免费公开课视频+资料+源码+经典牛逼 汇总篇【持续更新】

    博主推荐一:WP8.1最经典培训教程 博主点评:经典Windows Phone8.1 Runtime API培训最经典教程,此教程由传智播客蒋坤老师录制的一整套WP8.1入门级视频教程,讲授内容非常广 ...

  9. [JS1] 如何嵌入

    <html> <head> <title>在HTML文档中嵌入JavaScript代码是如何嵌入到HTML文档中的.</title> <scrip ...

  10. 使用SharePoint CSOM 编写高效的程序

    上一篇文章中简单的介绍了使用CSOM进行编程.今天主要讲一下CSOM使用中一些小技巧,可以让你的程序运行的更快. 单独加载某些属性 在上文中的例子,需要返回Web对象信息的时候,我们使用了如下的代码: ...