2011-11-29 78 views
1

我尝试通过TCP套接字进行一种聊天。服务器端在PHP和(应该)工作正常。双向插座(非阻塞)与c

不,我遇到了在客户端的问题(用C语言实现[C99]):

我想听听(读取)来自服务器的“新字节”,我也想每当用户输入新数据时向服务器发送(写入)“一些字节”。

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

感谢您的任何示例。

+0

您是否考虑过使用线程? –

+0

线程将以不好的方式解决问题。 –

回答

1

有一个函数叫做select,可以用于这个。它可以检查套接字是否有新的输入来读取,并且它有一个超时时间,所以它也可以用于你的定时器。

它存在于所有主要操作系统上的一种形式或其他形式。只要做一个谷歌搜索socket select <your operating system> example,你会得到一个船载的结果。


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

如果该指针作为NULL传递,那么没有超时,并且select可以无限期地阻塞。

要设置超时,你需要将timeval结构的tv_sec字段设置为秒数,和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结构被修改,以包含剩余的超时时间。

+0

谢谢。我知道我必须使用select。但我如何设置超时?选择也阻止....任何想法的例子?我无法通过Google搜索找到c的示例。 –

+0

找到了解决方案! http://rhoden.id.au/doc/sockets。html –

+0

您还发现一个断开的链接! – g33kz0r

0

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