如何在tcp/ip编程中模拟检测recv和send?

how to simulatenously detect recv and send in tcp/ip programming?

我正在尝试创建一个简单的信使程序,我刚刚介绍了 tcp/ip 使用 c 进行套接字编程的基础知识。

但是通过在 while 循环中包含 'recv' 和 'send',客户端-服务器每回合只能通信一次。我正在考虑让我的信使程序能够立即发送和接收任何消息。例如,如果另一方发送如此多的消息,我的程序应该能够接收多条消息。

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

我考虑的 B 计划是让服务器在日志文件中记录客户端之间的所有消息,并让客户端大约每秒同步一次聊天。

这是实用的 Messenger 应用程序所做的还是有更有效的方法?

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

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

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

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

这些接口的好处是它们随处可见;它们是便携式的。在这方面,poll 通常优于 select,因为后者对其可以处理的文件描述符数量有内置限制(通常限制为 1024)。事实上它比 select 稍微差一点:因为它实现了一个位图,其中每个位代表一个 fd,它甚至不能表示大于 1024 的文件描述符。poll 没有这样的限制。

系统特定的接口提供了一种更有效的方法来完成与 pollselect 相同的事情,但显然不能在系统之间移植。如果您不想重新发明轮子并围绕这些东西编写自己的包装器,您可能需要查看 libPhenom, libevent, or libev.

由于听起来您正在编写一个多用户聊天服务器,因此过程通常是:

  1. 可读数据的轮询套接字
  2. 从套接字读取数据
  3. 将数据发送给其他相关方
  4. 冲洗
  5. 重复

如果您不熟悉 Beej's Guide to Network Programming, it is a great resource for learning about the fundamentals. Indeed, he also has a section on "advanced techniques",它包含一个微型多用户聊天服务器。