简短问题
处理服务器端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;
}
我在this UNIX套接字常见问题解答中的旁注中找到了对Ctrl-C的评论:
[...](顺便说一下,带外通常也用于ctrl-C)。
据我所知,接收带外数据是使用recv()完成的,并将某个标志作为最后一个参数。但是,当我在上面的代码中使用recv()等待数据时,我无法同时读取带外数据。除此之外,我在没有oob-flag的情况下使用recv()获取某些东西。
答案 0 :(得分:2)
使用fcntl()将套接字设置为非阻塞,使用select()(在某些系统上使用pselect())来检查到达的数据。这是如何对套接字的当前条件进行采样,即它是否具有recv()数据以及是否可以接受send(),或者存在异常。不要只是坐在那里阻挡。
recv()返回尽可能多的可用信息,因为提供的缓冲区大小可以容纳。如果套接字已配置为接收带外数据(套接字选项SO_OOBINLINE)并且存在未读的OOB数据,则仅返回带外数据。调用ioctl()SIOCATMARK以确定是否还有未读取的带外数据。
当您收到OOB数据时,您无法在单个recv()调用中recv()超过OOB数据包的末尾,因此在这方面它是防范的。
我不知道什么是最佳做法,但是在其他已经缓冲的套接字数据之前抓住ctrl-c的想法是个好主意。