代码之家  ›  专栏  ›  技术社区  ›  Nick

C Socket程序-如何在更新stdout的读取时接受用户输入?

c
  •  2
  • Nick  · 技术社区  · 14 年前

    我用C语言编写了一个小的irc机器人应用程序,它只是将服务器消息写到屏幕上。这只是通过从服务器文件描述符读取while循环来完成的。如何同时接受输入?我现在要扩展它以接受用户输入,以便它可以用作客户端应用程序。我是C开发的新手,所以我不确定这是如何实现的。有人能给我举个例子或者给我指出一些文档的方向吗?

    如有任何帮助/建议,将不胜感激。

    编辑

    我是在Unix环境中开发的。

    谢谢

    3 回复  |  直到 14 年前
        1
  •  4
  •   kanaka    14 年前

    尽可能避免多进程和多线程编程。那条路通向痛苦。使用事件驱动编程。对于您想要做的事情,事件驱动编程是 容易多了 ,也会有同样的表现。在C中,两种主要的方法是进行事件驱动编程(与I/O相关) select poll

    下面是使用select的工作示例:

    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/time.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <errno.h>
    
    int
    main(void)
    {
        fd_set rfds;
        struct timeval tv;
        int retval, len;
        char buf[4096];
    
        while (1) {
            /* Watch stdin (fd 0) to see when it has input. */
            FD_ZERO(&rfds);
            FD_SET(0, &rfds);
    
            /* Wait up to five seconds. */
            tv.tv_sec = 5;
            tv.tv_usec = 0;
    
            retval = select(1, &rfds, NULL, NULL, &tv);
            /* Don't rely on the value of tv now! */
    
            if (retval == -1) {
                perror("select()");
                exit(EIO);
            } else if (retval) {
                printf("Data is available now.\n");
            } else {
                printf("No data within five seconds.\n");
                continue;
            }
            if (FD_ISSET(0, &rfds)) {
                len = read(0, buf, 4096);
                if (len > 0) {
                    buf[len] = 0;
                    printf("Got data on stdin: %s\n", buf);
                } else {
                    // fd closed
                    perror("read()");
                    exit(EIO);
                }
    
            }
        }
    }
    

    FD_SET用于创建要选择的文件描述符列表(从中获取事件)。在select成功返回(意味着有一个要处理的事件)之后,可以使用FD_ISSET查找导致事件的文件描述符。在您的例子中,您将有一个打开的套接字文件描述符,您将添加到集合中并进行适当的处理。

    有用的文档包括以下手册页:

    • man 2 select
    • man 2 poll
    • man 3 read
    • man 3 open
        2
  •  2
  •   Aman Jain    14 年前

    你想同时监视插座和标准输入。如果这是正确的,请查看此处的select()系统调用: http://beej.us/guide/bgnet/output/html/singlepage/bgnet.html#select

        3
  •  -2
  •   Alexander Rafferty    14 年前

    有一个叫做多线程的小东西。多线程(C++)完全依赖于操作系统或外部库。

    如果您使用的是windows,那么可以使用“windows.h”中定义的beginthread()和endthread()。

    它相当容易使用。