欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

【网络编程】——connect函数遇见EINTR的处理

发布时间:2025/6/15 编程问答 38 豆豆
生活随笔 收集整理的这篇文章主要介绍了 【网络编程】——connect函数遇见EINTR的处理 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

  最近在公司项目中突然报错如下 “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 错误的时候,处理过程如下:

1 int check_conn_is_ok(socket_t sock) { 2 struct pollfd fd; 3 int ret = 0; 4 socklen_t len = 0; 5 6 fd.fd = sock; 7 fd.events = POLLOUT; 8 9 while ( poll (&fd, 1, -1) == -1 ) { 10 if( errno != EINTR ){ 11 perror("poll"); 12 return -1; 13 } 14 } 15 16 len = sizeof(ret); 17 if ( getsockopt (sock, SOL_SOCKET, SO_ERROR, 18 &ret, 19 &len) == -1 ) { 20 perror("getsockopt"); 21 return -1; 22 } 23 24 if(ret != 0) { 25 fprintf (stderr, "socket %d connect failed: %s\n", 26 sock, strerror (ret)); 27 return -1; 28 } 29 30 return 0; 31 }

  调用时如下:

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

 

总结

以上是生活随笔为你收集整理的【网络编程】——connect函数遇见EINTR的处理的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。