Kqueue系统调用和非阻滞连接。在情况下,我应该使用什么代码测试错误?

发布于 2025-02-06 11:04:42 字数 2344 浏览 4 评论 0原文

今天,我对Linux代码进行了少量更改。代码是一种 PING-PONG网络程序。客户端写下“你好”,服务器响应 “你好”。就是这样。

现在我使用FreeBSD。因此,自然epollkqueue取代的机制。 执行连接的代码的一部分引起了我的注意。下面修剪了代码 要展示我如何与Linux进行非块连接。

n = epoll_wait (ep_fd, ep_evs, YPOLL_EPOLL_NEVENTS, timeout_ms);
/* check epoll return for errors */

/* ... */

for(i = 0; i < n; ++i) { /* service epoll events */
 sock  = (sock*)ep_evs[i].data.ptr; /* user data */
 state = sock->state; /* store socket state: paired, connecting, closed, listening */
 mask  = ep_evs[i].events;

 /* connection in progress may have errors at the very start */
 if(state != CONNECTION_IN_PROGRESS){ 
  if(mask & EPOLLHUP){ /* hang up, both read/write not possible */
   /* do something */
   continue; /* next event */
  }
  if(mask & EPOLLERR) { /* error, or pipe read end has been closed */
   /* do something */
   continue; /* next event */
  }
 }

 /* test for various events */
 /* ... */

 /* fd is a socket that is yet to be connected */
 else if((state == CONNECTION_IN_PROGRESS) && (mask & EPOLLOUT)) {
  int v = /* call getsockopt for `SO_ERROR` */
  if(v != 0){ /* connection failed */
   /* do something, maybe print error */
   continue; /* next event */
  }
  /* connection passed */
  /* maybe add the socket to the list of connected sockets ? */
  continue; /* next event */
 }

}

上述对我进行非阻滞连接到服务器的工作。与Linux。 在这里,我更接近问题部分。 kqueue接口具有标志fflags 为活动设置。

该计划是使用FreeBSD进行操作,以便代码可以进行非阻滞连接。 我是否必须调用getsockopt来测试错误, 或者,我最好检查使用flagsfflags的错误?

更新

我看到这个问题在措辞中有些不清楚。我改写并解释。对于我来说,对于我来说,唯一的方法是通过非阻止连接捕获错误, - 呼叫getsockopt,获取so_errorepollhup的测试,不会捕获所有错误。带有getsockopt的代码是我唯一的选择。我已经测试了各种设置,并且使用so_error进行检查确实涵盖了一些错误路径,而Epoll错误报告没有。同样,我必须承认,以上是我的系统,通过我的网络设置等。

我的问题是,will kqueue set eof fflags < /code>如果有非阻滞连接的错误?最好是,我可以安全地假设对eof的测试涵盖了所有错误案例?

Update

自上次写入以来,我已经测试了一些具有非阻滞连接的错误的代码路径。标志将设置为以下内容:timeDoutconnresetconnrefused。我无法测试所有可能的代码路径,因此我现在只是为了测试ev_eof

Today, I was making small changes to my Linux code. The code is a kind of
ping-pong network program. The client writes "Hello", the server responds with
"Hello". That is all to it.

Now I use FreeBSD. So naturally epoll mechanism being replaced by kqueue.
The part of code that did a connect had caught my attention. The below is trimmed down code
to show how I do non-blocking connect with Linux.

n = epoll_wait (ep_fd, ep_evs, YPOLL_EPOLL_NEVENTS, timeout_ms);
/* check epoll return for errors */

/* ... */

for(i = 0; i < n; ++i) { /* service epoll events */
 sock  = (sock*)ep_evs[i].data.ptr; /* user data */
 state = sock->state; /* store socket state: paired, connecting, closed, listening */
 mask  = ep_evs[i].events;

 /* connection in progress may have errors at the very start */
 if(state != CONNECTION_IN_PROGRESS){ 
  if(mask & EPOLLHUP){ /* hang up, both read/write not possible */
   /* do something */
   continue; /* next event */
  }
  if(mask & EPOLLERR) { /* error, or pipe read end has been closed */
   /* do something */
   continue; /* next event */
  }
 }

 /* test for various events */
 /* ... */

 /* fd is a socket that is yet to be connected */
 else if((state == CONNECTION_IN_PROGRESS) && (mask & EPOLLOUT)) {
  int v = /* call getsockopt for `SO_ERROR` */
  if(v != 0){ /* connection failed */
   /* do something, maybe print error */
   continue; /* next event */
  }
  /* connection passed */
  /* maybe add the socket to the list of connected sockets ? */
  continue; /* next event */
 }

}

The above works for me to do a non-blocking connect to a server. With Linux.
And here I get closer to the question part. The kqueue interface has flags and fflags
set for the event.

The plan is to do the same with FreeBSD, so that code will do a non-blocking connect.
Do I have to call getsockopt to test for the error,
or I would better check for an error with flags and fflags?

Update

I see that the question somewhat unclear in wording. I rephrase and explain. With Linux, the only way, for me, to catch an error with a non-blocking connect, - is to call getsockopt, getting SO_ERROR. Tests for epoll masks, like EPOLLHUP, does not catch all errors. The code with getsockopt, is the only option for me. I had tested various setups, and the check with SO_ERROR does cover some error paths that epoll error reporting does not. Again, I have to admit, that the above is for my system, with my network setup, etc.

My question is, will kqueue set EOF and fflags in case of an error with non-blocking connect? And preferably, can I safely assume that testing for EOF will cover all error cases?

Update

Since the last write up, I've tested some code paths of an error with a non-blocking connection. The flags are set for the following: TIMEDOUT, CONNRESET, CONNREFUSED. I can not test all possible code paths, so I just settle for testing EV_EOF, for now.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文