Unix TCP 服务器和 UDP 服务器
为什么TCP服务器的设计大多是这样的:每当它接受一个连接时,就会调用一个新的进程来处理它。但是,为什么在 UDP 服务器的情况下,大多数情况下只有一个进程来处理所有客户端请求?
Why is the design of TCP servers mostly such that whenever it accepts a connection, a new process is invoked to handle it . But, why in the case of UDP servers, mostly there is only a single process that handles all client requests ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
如前所述,TCP 和 UDP 之间的主要区别在于 UDP 是无连接的。
使用 UDP 的程序只有一个用于接收消息的套接字。因此,如果您只是阻止并等待消息,那就没有问题。
如果使用 TCP,则每个连接的客户端都会获得一个套接字。那么你不能只是阻塞并等待一个套接字接收某些内容,因为还有其他套接字必须同时处理。
所以你有两个选择,要么使用非阻塞方法,要么使用线程。当您没有必须处理每个客户端的 while 循环时,代码通常会简单得多,因此通常首选线程。如果使用阻塞方法,还可以节省一些 CPU 时间。
The main difference between TCP and UDP is, as stated before, that UDP is connectionless.
A program using UDP has only one socket where it receives messages. So there's no problem if you just block and wait for a message.
If using TCP you get one socket for every client which connects. Then you can't just block and wait for ONE socket to receive something, because there are other sockets which must be processed at the same time.
So you got two options, either use nonblocking methods or use threads. Code is usually much simpler when you don't have one while loop which has to handle every client, so threading is often prefered. You can also save some CPU time if using blocking methods.
当您通过 TCP 连接与客户端通信时,您保持 TCP 会话。因此,当建立新连接时,您需要单独的进程(或线程,无论它如何实现以及使用什么操作系统)并保持对话。但是,当您使用 UDP 连接时,您可能会收到数据报(并且您将被告知发送者的 IP 和端口),但通常情况下您无法对其进行响应。
When you talk with client via TCP connection you maintain TCP session. So when new connection established you need separate process(or thread, no matter how it implemented and what OS used) and maintain conversation. But when you use UDP connection you may recieve datagram(and you will be informed about senders ip and port) but in common case you cannot respond on it.
首先,经典的 Unix 服务器范例是基于过滤器的。例如,可以在 /etc/services 中配置各种网络服务,并且像 inetd 这样的程序会侦听所有 TCP 和 UDP 套接字以获取传入连接和数据报。当连接/DG 到达时,它会分叉,使用 dup2 系统调用将 stdin、stdout 和 stderr 重定向到套接字,然后执行服务器进程。 您可以采取任何程序从stdin读取并写入stdout并将其转换为网络服务,例如grep。
根据Steven在《Unix网络编程》中的说法,服务器I/O模型有五种(第154页) ):
此外,服务器可以是迭代的或并发的。
您会问为什么 TCP 服务器通常是并发的,而 UDP 服务器通常是迭代的。
UDP方面比较容易回答。通常,UDP 应用程序遵循简单的请求响应模型,其中客户端发送一个简短的请求,然后发送一个回复,每对构成一个独立的事务。 UDP 服务器是唯一使用 Signal Drive I/O 的服务器,而且很少使用。
TCP 有点复杂。迭代服务器可以使用上述任何 I/O 模型,#4 除外。单处理器上最快的服务器实际上是使用非阻塞 I/O 的迭代服务器。然而,这些实现起来相对复杂,再加上 Unix 过滤器习惯用法,传统上这是使用阻塞 I/O 并发模型的主要原因,无论是多进程还是多线程。现在,随着常见的多核系统的出现,并发模型也具备了性能优势。
First of all, the classic Unix server paradigm is filter based. For example, various network services can be configured in /etc/services and a program like inetd listens on all of the TCP and UDP sockets for incoming connections and datagrams. When a connection / DG arrives it forks, redirects stdin, stdout and stderr to the socket using the dup2 system call, and then execs the server process. You can take any program which reads from stdin and writes to stdout and turn it into a network service, such as grep.
According to Steven's in "Unix Network Programming", there are five kinds of server I/O models (pg. 154):
In addition the servers can be either Iterative or Concurrent.
You ask why are TCP servers are typically concurrent, while UDP servers are typically iterative.
The UDP side is easier to answer. Typically UDP apps follow a simple request response model where a client sends a short request followed by a reply with each pair constituting a stand alone transaction. UDP servers are the only ones which use Signal Drive I/O, and at the very rarely.
TCP is a bit more complicated. Iterative servers can use any of the I/O models above, except #4. The fastest servers on a single processor are actually Iterative servers using non-blocking I/O. However, these are considered relatively complex to implement and that plus the Unix filter idiom where traditionally the primary reasons for use of the concurrent model with blocking I/O, whether multiprocess or multithreaded. Now, with the advent of common multicore systems, the concurrent model also has the performance advantage.
你的概括太笼统了。您可能会在基于 Unix 的服务器上看到这种模式,其中进程创建的成本很低。基于 .NET 的服务将使用线程池中的新线程,而不是创建新进程。
Your generalization is too general. This is a pattern you might see with a Unix-based server, where process creation is inexpensive. A .NET-based service will use a new thread from the thread pool instead of creating a new process.
在等待 I/O 时可以继续执行有用工作的程序
通常是多线程的。进行大量计算的程序
可以整齐地分为单独的部分可以受益于
多线程,如果有多个处理器。提供服务的程序
有时,大量的网络请求可以通过拥有一个池而受益
可用线程来服务请求。 GUI 程序还需要
执行计算可以从多线程中受益,因为它允许
主线程继续为 GUI 事件提供服务。
这就是我们使用 TCP 作为互联网协议的原因。
Programs that can continue to do useful work while they are waiting for I/O
will often be multithreaded. Programs that do lots of computation which
can be neatly divided into separate sections can benefit from
multithreading, if there are multiple processors. Programs that service
lots of network requests can sometimes benefit by having a pool of
available threads to service requests. GUI programs that also need to
perform computation can benefit from multithreading, because it allows the
main thread to continue to service GUI events.
Thats why we use TCP as an internet protocol.