我閱讀了有關 express 中使用的 .listen() 方法的檔案。我可以使用該方法并設定一個偵聽 HTTP 請求的服務器。
然而,由于我對編碼相當陌生,我發現在使用 .listen() 方法時很難掌握真正發生的事情。“偵聽連接”的高級解釋對我沒有幫助。
我認為,如果我能真正看到函式而不是僅僅呼叫它,這會變得更容易。
很感謝任何形式的幫助
uj5u.com熱心網友回復:
簡而言之,Expressapp.listen()方法創建一個 http 服務器物件,然后將其配置為在特定埠和 IP 地址上接收傳入的 TCP 連接,以便當客戶端請求連接到該埠并發送 http 請求時,服務器可以接收該 http請求并處理它,發送回應。中的代碼app.listen()顯示在下面的答案中 - 盡管它所做的只是向下呼叫 http 服務器物件中的下一層。
以下是有關其作業原理的較低級別的詳細資訊。
當服務器希望開始偵聽傳入連接時,它會通過創建套接字以及binding特定埠和 IP 地址來通知本地 TCP 堆疊。這實質上為該特定服務器保留了傳入埠(不允許其他服務器也系結到該埠)。因此,例如,在默認埠上的常規 http 服務器上,您將系結到埠 80。這種型別的系結套接字僅用于傳入連接,而不用于與客戶端的雙向通信。
然后,服務器通知 TCP 堆疊它已準備好接收傳入連接。在 TCP 級別,這稱為listen。在 nodejs 中,系結和監聽步驟合并為一個步驟,稱為listen.
從那時起,每當本地 TCP 堆疊接收到目標是服務器系結的 IP 地址和埠的傳入連接請求時,該傳入連接將被接受并插入到為該 IP 地址配置的服務器的佇列中和港口。通常會有最大數量的傳入連接可以以這種方式排隊,如果超過該數量,則連接將被拒絕。如果服務器得到“備份”并且在處理傳入連接方面落后,這將管理負載并保護主機。
然后,對于每個新的傳入連接,TCP 堆疊都會通知服務器。一旦服務器接受該連接,它就可以開始讀取客戶端通過套接字發送的任何資料。在 HTTP 服務器使用 HTTP 協議的情況下,這將是初始請求協議、方法、版本、標頭和任何正文資料。對于不同型別的服務器,資料將采用不同的格式。
這是服務器的有用圖:

來源:https : //medium.com/javarevisited/fundamentals-of-socket-programming-in-java-bc9acc30eaf4
- 服務器創建一個用于服務器接受新連接的套接字。
- 它
bind是連接到特定 IP 地址和埠的套接字,因此它只會被告知針對該 IP 地址和埠的傳入連接。 - 它
listen在該埠上通知 TCP 堆疊它已準備好接受傳入連接。 - 當它收到傳入連接的通知時,它
accept就是傳入連接。 - 然后它可以通過新套接字讀取和寫入該新連接。
- 然后,稍后,傳入套接字關閉以完成客戶端事務。
app.listen()Express 中的方法封裝了這些步驟和其他一些步驟。在內部(在 Express 中),代碼如下所示:
app.listen = function listen() {
var server = http.createServer(this);
return server.listen.apply(server, arguments);
};
您可以在此處的開源存盤庫中看到該方法。
為了讓 http 服務器為上面的步驟 1-6 做好準備,這會在 nodejs 中創建 http 服務器物件,然后將 注冊app為該服務器物件的請求偵聽器(因此它將收到傳入的 http 請求的通知)。
Then, the call to server.listen() encapsulates steps 1-3 above.
Step 4 happens inside the http server object implementation and the app object is called when a new connection has been established and a new HTTP request is available. The http server reads the initial request and parses the http protocol and that initial request is already made available to the app for routing to the appropriate handler.
Then, subsequent calls such as res.send() or res.json() write a response back on the http socket and close the socket or res.end() will close it directly (steps 5 and 6 above).
Some other useful references:
Why is bind() used in TCP? Why is it used only on server side and not in client side? - Helps explain how a port and IP address define the TCP endpoint represented by a server. This port has to be known by the client so it can specifically request to connect to that port. The client end of the socket also has an IP address and a port, but its port can be dynamically assigned, thus the client does not have to bind to a specific port itself. The four pieces of data [server IP, server port, client IP, client port] define a specific TCP connection.
How TCP sockets work - has a good section about how new connections to a server work.
Understanding socket and port in TCP - talks about active and passive sockets. Passive sockets are sockets in "listen" mode used to accept incoming connections. Active sockets are two-way communications channels between two TCP endpoints.
Transmission Control Protocol (TCP) - more details on the various aspects of TCP from initiating a listening server, initiating a client connection to that server, through packet transmission to closing the socket.
There are a gazillion other references on the topic on the web. You can probably find 1000 articles on any single aspect of TCP that you might want more info about.
I think, this could be made easier if I could actually see the function instead of only calling it.
The underlying code for listen is inside the operating system's TCP stack and is not part of nodejs or Express. Express relies on the nodejs http server object as its interface to that and the nodejs http server object uses native code (built into nodejs) to call libuv (which is a cross platform C library that nodejs uses for networking and other things). Then, libuv talks to the underlying operating system APIs to reach the actual TCP stack on that target host. All of this is to put the server socket into listen mode so it can be notified of new incoming client connections to that target IP address and port.
Here's some doc on the related portions of the Linux TCP API if you want to see what the underlying TCP interface and description of that interface is:
socket()- https://linux.die.net/man/7/socket
bind()- https://linux.die.net/man/2/bind
listen()- https://linux.die.net/man/2/listen
并且,nodejs 用于網路的libuv 庫的部分內容:
TCP 句柄 - http://docs.libuv.org/en/v1.x/tcp.html
服務器listen()和accept()- http://docs.libuv.org/en/v1.x/stream.html#c.uv_listen
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/386318.html
