POSIX 套接字:如何检测通过 Telnet 发送的 Ctrl-C?

发布于 2024-09-05 06:09:57 字数 864 浏览 4 评论 0原文

简短问题
在服务器端处理通过 Telnet 发送的 Ctrl-C 事件的正确方法是什么?

长问题
在套接字上调用recv()之后,我想适当地处理一些情况。其中之一是在收到 Ctrl-C 时返回特定的错误代码。检测这个的正确方法是什么?以下内容有效,但似乎不正确:

size_t recv_count;
static char ctrl_c[5] = {0xff, 0xf4, 0xff, 0xfd, 0x06};

recv_count = recv(socket, buffer, buffer_size, 0);

if (recv_count == sizeof(ctrl_c) &&
    memcmp(buffer, ctrl_c, sizeof(ctrl_c) == 0)
{
    return CTRL_C_RECEIVED;
}

我在 UNIX 套接字常见问题解答:

[...](顺便说一句,带外也经常用于该 ctrl-C)。

据我了解,接收带外数据是使用带有特定标志作为最后一个参数的recv()来完成的。但是,当我像上面的代码中那样使用 recv() 等待数据时,我无法同时读取带外数据。除此之外,我在没有 oob 标志的情况下使用 recv() 得到了一些东西

Short Question
What's the right way to handle a Ctrl-C event sent over Telnet on the server side?

Long Question
After calling recv() on a socket, I'd like to handle some situations appropriately. One of them is to return a certain error code when Ctrl-C was received. What's the correct way to detect this? The following works, but it just doesn't seem right:

size_t recv_count;
static char ctrl_c[5] = {0xff, 0xf4, 0xff, 0xfd, 0x06};

recv_count = recv(socket, buffer, buffer_size, 0);

if (recv_count == sizeof(ctrl_c) &&
    memcmp(buffer, ctrl_c, sizeof(ctrl_c) == 0)
{
    return CTRL_C_RECEIVED;
}

I found a comment on Ctrl-C in a side-note in this UNIX Socket FAQ:

[...] (by the way, out-of-band is often used for that ctrl-C, too).

As I understand, receiving out-of-band data is done using recv() with a certain flag as the last parameter. But when I'm waiting for data using recv() as I do in the code above, I can't read out-of-band data at the same time. Apart from that, I'm getting something using recv() without that oob-flag.

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

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

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

狠疯拽 2024-09-12 06:09:57

使用 fcntl() 将套接字设置为非阻塞,使用 select()(某些系统上为 pselect())检查到达的数据。这就是如何采样套接字的当前状况,即是否有数据发送给recv(),是否可以接受send(),或者是否有异常。不要只是坐在那里阻挡。

recv() 返回所提供的缓冲区可以容纳的尽可能多的可用信息。如果套接字已配置为接收带外数据(套接字选项 SO_OOBINLINE)并且存在未读取的 OOB 数据,则仅返回带外数据。调用 ioctl() SIOCATMARK 来确定是否还有更多带外数据未读取。

当您接收 OOB 数据时,您无法在单个 recv() 调用中调用超过 OOB 数据包末尾的 recv() ,因此在这方面它是万无一失的。

我不知道什么是最佳实践,但在其他已缓冲的套接字数据之前获取 ctrl-c 的想法是一个很好的想法。

Set the socket to non-blocking with fcntl(), use select() (pselect() on some systems) to check for arriving data. That is how to sample a socket's current condition, i.e. whether it has data to recv() and if can accept a send(), or there is an exception. Don't simply sit there blocking.

A recv() returns as much available information as the size of the buffer supplied can hold. If the socket has been configured to receive of out-of-band data (socket option SO_OOBINLINE) and there is unread OOB data, only out-of-band data is returned. Call ioctl() SIOCATMARK to determine whether any more out-of-band data remains un-read.

When you receive OOB data you cannot recv() past the end of the OOB packet in a single recv() call, so it is goof-proof in that regard.

I don't know what is considered best practice, but the idea of grabbing ctrl-c ahead of other already buffered socket data is a good one.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文