2010-06-10 55 views
5

Short Question
在服务器端通过Telnet发送Ctrl-C事件的正确方法是什么?POSIX套接字:如何检测通过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; 
} 

我发现一个侧面说明上按Ctrl-C评论中this Unix套接字FAQ:

[...] (顺便说一下,out-of-band通常也用于该ctrl-C)。

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

+0

通过telnet发送Ctrl-D作为^ D(0x04)字符 – 2016-04-21 12:56:57

回答

2

使用fcntl()将套接字设置为非阻塞,在某些系统上使用select()(pselect())来检查是否到达数据。这就是如何对套接字的当前条件进行采样,即它是否具有要recv()的数据并且是否可以接受send(),或者是否存在异常。不要简单地坐在那里阻止。

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

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

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

+0

实际上,我正在编写一个内部使用的库,它为套接字提供了便利函数(这里已经有一些fcntl()和select() ),所以这个问题并不是特定于具体应用程序的实现,而是“我的酷图书馆可以帮助的另一件事”。我希望能够捕捉诸如没有OOB数据的ctrl-c等事件,以保持简单。 我同意不只是围坐在recv()等待,我的图书馆支持阻塞和非阻塞模式,但它会很好地实现这个东西一次,它每次都工作(tm)。 无论如何,谢谢你的回答! – 2010-06-10 14:10:00

+0

http://linux.softpedia.com/get/Programming/Libraries/sWrapper-35278.shtml – 2010-06-10 18:44:09

+0

上面的链接是一些类似的努力使插座更少涉及的一个例子。国际海事组织更多参与的方法可以让您根据您的确切需求调整设置。如果不在代码中添加许多复杂选项,“确切需求”可能很难做到。 这有点解除了你努力的目的。 – 2010-06-10 18:46:49