带c的双向套接字(非阻塞)

时间:2011-11-29 11:30:47

标签: c sockets nonblocking

我尝试通过TCP套接字进行一种聊天。服务器端在php中实现,并且(应该)正常工作。

不,我在客户端遇到问题(在c [c99]中实现):

我想从服务器监听(读取)“新字节”,并且我还想在用户输入新数据时向服务器发送(写入)“一些字节”。

现在的问题是: - >我如何监听传入流量(读取)并仍然能够每1秒调用一次回调,我可以检查要发送到服务器的新字节? 我知道我必须使用select(系统调用),但我不知道如何处理超时等。选择也在一段时间内阻塞。

谢谢你的任何一个例子。

3 个答案:

答案 0 :(得分:1)

有一个名为select的函数可用于此目的。它可以检查要读取的套接字上是否有新输入,并且它有一个超时,因此它也可以用于您的计时器。

它在所有主要操作系统上以一种形式存在。只需对socket select <your operating system> example进行谷歌搜索,您就可以获得一系列结果。


select的最后一个参数用于超时。它是指向struct timeval的指针,该结构包含用于设置超时的字段。

如果此指针作为NULL传递,则没有超时,select可以无限期阻止。

要设置超时,您需要将tv_sec结构的timeval字段设置为秒数,将tv_usec字段设置为微秒数(必须更少)超过一百万)。通过将这些字段设置为零,您可以将超时设置为零,即只需快速轮询。

如果select返回零,则表示超时。

示例,1.5秒超时:

for (;;)
{
    fd_set readset;
    int maxfd;

    /* Initialize and set `readset` and `maxfd` */

    struct timeval tv;
    tv.tv_sec  = 1;
    tv.tv_usec = 500000;

    int res = select(maxfd + 1, &readset, NULL, NULL, &tv);

    if (res == -1)
        perror("select");  /* Error */
    else if (res == 0)
    {
        /* Timeout, do something */
    }
    else
    {
        /* A socket in `readset` is readable */
    }
}

如果select在超时之前返回,则修改timeval结构以包含超时的剩余时间。

答案 1 :(得分:0)

使用select系统调用,并根据需要设置timeout参数。 Beej's guide仍然是一个很好的来源,有很多示例代码。

答案 2 :(得分:0)

使用选择system来电。您还可以找到有用的this