简体   繁体   English

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

[英]POSIX Sockets: How to detect Ctrl-C sent over Telnet?

Short Question 简短的问题
What's the right way to handle a Ctrl-C event sent over Telnet on the server side? 处理服务器端Telnet上发送的Ctrl-C事件的正确方法是什么?

Long Question 长问题
After calling recv() on a socket, I'd like to handle some situations appropriately. 在套接字上调用recv()之后,我想适当地处理一些情况。 One of them is to return a certain error code when Ctrl-C was received. 其中之一是在收到Ctrl-C时返回某个错误代码。 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: 我在这个 UNIX Socket FAQ的旁注中找到了对Ctrl-C的评论:

[...] (by the way, out-of-band is often used for that ctrl-C, too). [...](顺便说一下,带外通常也用于ctrl-C)。

As I understand, receiving out-of-band data is done using recv() with a certain flag as the last parameter. 据我所知,接收带外数据是使用recv()完成的,并将某个标志作为最后一个参数。 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. 但是,当我在上面的代码中使用recv()等待数据时,我无法同时读取带外数据。 Apart from that, I'm getting something using recv() without that oob-flag. 除此之外,我正在使用recv()获得一些没有oob-flag的东西。

Set the socket to non-blocking with fcntl(), use select() (pselect() on some systems) to check for arriving data. 使用fcntl()将套接字设置为非阻塞,使用select()(在某些系统上使用pselect())来检查到达的数据。 That is how to sample a socket's current condition, ie whether it has data to recv() and if can accept a send(), or there is an exception. 这是如何对套接字的当前条件进行采样,即它是否具有recv()数据以及是否可以接受send(),或者存在异常。 Don't simply sit there blocking. 不要简单地坐在那里阻挡。

A recv() returns as much available information as the size of the buffer supplied can hold. recv()返回与提供的缓冲区大小相同的可用信息。 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. 如果套接字已配置为接收带外数据(套接字选项SO_OOBINLINE)并且存在未读的OOB数据,则仅返回带外数据。 Call ioctl() SIOCATMARK to determine whether any more out-of-band data remains un-read. 调用ioctl()SIOCATMARK以确定是否还有未读取的带外数据。

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. 当您收到OOB数据时,您无法在单个recv()调用中recv()超过OOB数据包的末尾,因此在这方面它是防篡改的。

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. 我不知道什么是最佳实践,但是在其他已经缓冲的套接字数据之前获取ctrl-c的想法是个好主意。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM