如何突破fgets?

时间:2014-01-14 20:37:21

标签: c fgets

我正在撰写一个简单的即时通讯客户端&服务器来获取套接字编程的句柄。

我的客户有两个主题:

  • 线程A与服务器有一个流套接字连接 在循环中执行readline,打印出它接收的文本行 从服务器。如果readline返回EOF,则循环退出。
  • 线程B在循环中使用fgets侦听来自用户的键盘输入。当用户按下回车键时,它会将该行发送到服务器(因此它可以将其转发给其他客户端)。

当用户按下Ctrl-D时,客户端向服务器发送一条特殊消息,说“客户端想要断开连接”,此时服务器关闭该用户的连接文件描述符。这导致线程A退出循环,因为readline函数返回EOF。然后,线程A关闭连接文件描述符并完成。

同时,线程B仍在收听用户输入的键盘输入。理想情况下,fgets会提前中断并让用户知道另一个客户端已断开连接。

无论如何要做或者我需要使用不同的输入函数或库吗?

3 个答案:

答案 0 :(得分:5)

首先,如果您正在尝试编写套接字函数,请不要使用fgets()或使用缓冲IO的任何其他内容,也称为FILE *。而是使用文件描述符(fd)。通常,应避免以“f”开头的每个libc函数。您需要readwrite

其次,您希望使用select()阅读异步I / O,而不是弄清楚如何“突破”fgets()

第三,我可以在这里给你一个教程,或者我可以告诉你google,或者看看http://en.wikipedia.org/wiki/Asynchronous_I/O但你真正想要找到的是Stephens的副本(来自内存“Unix中的高级编程”)环境“是你想要的,但实际上你应该购买所有这些并将它们带到你的身体,同时你睡觉,希望通过渗透来学习。”

第四,我知道你说你想用线程来做这件事。如果你真的想这样做,你可以用pthread_cancel()杀死一个线程,然后重新启动它。别。做得好。你不需要线程。

答案 1 :(得分:0)

在Windows环境中,fgets是一个“阻塞”调用。因此,发出它的线程会等到它有一些输入。

没问题,只要fgets进入“Alertable Wait”就可以通过ExitThread(0)语句取消等待的I / O.

同样,在Windows中,在等待的线程中发出ExitThread(0)语句的方法是为线程调度APC(即QueueUserAPC())并使该调度方法发出ExitThread(声明。

我刚刚为我写的一些代码做了这个。我知道如果该线程发出了可变的等待,APC将导致线程退出。我不知道fgets是否在Windows中执行此操作,这是您需要弄清楚的。如果没有,那么使用一个I / O语句。注意。在Windows中,当I / O可用于对象时,当手柄发出信号时,您的代码可以在对象的句柄上使用WaitSingleObjectEx()发出Alertable等待。

在“MSDN APC”上进行互联网搜索,你会发现微软的各种文档。

答案 2 :(得分:-1)

P线程?使用pthread_kill发送SIGHUP。这将导致fgets退出并将errno设置为EINTR。在它退出到线程B之前从线程A发送它。您可能必须通过pthread_sigmask和sigaction来使用信号处理程序和掩码,具体取决于您想要获得的花哨程度。