如何同时检测recv并发送tcp / ip编程?

时间:2015-01-03 17:45:19

标签: c tcp tcp-ip

我正在尝试创建一个简单的Messenger程序,我刚刚介绍了使用c的tcp / ip socket编程的基础知识。

但是包括' recv'和'发送'在while循环中,客户端 - 服务器每回合只能进行一次通信。我想让我的信使程序能够立即发送和接收任何消息。例如,如果另一方发送了这么多消息,我的程序应该能够接收多条消息。

我想这一切都归结为recv()和send()不能在while循环中单独完成的问题。 如何管理这些函数以异步操作?

我想的计划B就是让服务器在日志文件中记录客户端之间的所有消息,并使客户端每隔一秒左右同步其聊天。

这是实用信使应用程序的功能还是更有效的方法呢?

1 个答案:

答案 0 :(得分:3)

人们可以通过多种方式在高性能网络服务器中处理此问题,但您可能感兴趣的方式是使用基于事件的I / O.

基本上,您可以在现代非嵌入式硬件上使用的任何操作系统都具有基于事件的I / O API。事实上,通常有一些可供选择:

  • select(2)
  • poll(2)
  • Linux上的
  • epoll(2)
  • BSD和OS X上的
  • kqueue(2)
  • Solaris上的
  • portfs/dev/poll和forks

为什么要使用其中任何一种而不是另一种? selectpoll都遇到这样的问题,即每次调用时都会将大量信息数据复制到内核中或从内核中复制出来。此大小相对于并发连接数呈线性增长。

这些界面的优点是它们在任何地方都得到了实施;它们是便携式的。在这方面,poll通常优先于select,因为后者对其可以处理的文件描述符的数量具有内置限制(通常以1024为界)。实际上它对select稍微差一些:因为它实现了一个位图,其中每个位代表一个fd,它甚至不能代表大于1024的文件描述符。poll不会受到这种限制。

特定于系统的接口提供了一种更有效的方法来执行与pollselect相同的操作,但显然在系统之间不可移植。如果您不想重新发明轮子并围绕这些事情编写自己的包装,您可能需要查看libPhenomlibeventlibev

由于这听起来像是在编写多用户聊天服务器,因此该过程通​​常是:

  1. 用于可读数据的轮询套接字
  2. 从套接字中读取数据
  3. 将数据发送给其他感兴趣的人士
  4. 冲洗
  5. 重复
  6. 如果您不熟悉Beej's Guide to Network Programming,那么它是了解基础知识的绝佳资源。实际上,他还有一个section on "advanced techniques",其中包括一个小型的多用户聊天服务器。