閱讀本文,應具備以下 2 項前置技術基礎 1. NAT traversal 2. UDP 穿透 TCP 穿透與 […]
閱讀本文,應具備以下 2 項前置技術基礎
1. NAT traversal
2. UDP 穿透
TCP 穿透與 UDP 最大的差異,在於「同 1 個 TCP socket 無法被綁定 2 次以上」
這是由於最早的 Berkeley sockets 標準 API 限制
只要解除這個限制,便能夠仿照 UDP 穿透的流程實現 TCP 穿透
這裡我們需要藉助系統 API 的力量
事實上,多數作業系統對於 socket API 已提供現成的擴充選項
通過關鍵字 SO_REUSEADDR,開發者能夠輕鬆地將埠口定義為「可被重用」
Linux (glibc) 文檔說明,範例:
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(value));
Windows Sockets 2 文檔說明
Using SO_REUSEADDR
The SO_REUSEADDR socket option allows a socket to forcibly bind to a port in use by another socket. The second socket calls setsockopt with the optname parameter set to SO_REUSEADDR and the optval parameter set to a boolean value of TRUE before calling bind on the same port as the original socket. Once the second socket has successfully bound, the behavior for all sockets bound to that port is indeterminate. For example, if all of the sockets on the same port provide TCP service, any incoming TCP connection requests over the port cannot be guaranteed to be handled by the correct socket — the behavior is non-deterministic. A malicious program can use SO_REUSEADDR to forcibly bind sockets already in use for standard network protocol services in order to deny access to those service. No special privileges are required to use this option.
If a client application binds to a port before a server application is able to bind to the same port, then problems may result. If the server application forcibly binds using the SO_REUSEADDR socket option to the same port, then the behavior for all sockets bound to that port is indeterminate.
The exception to this non-deterministic behavior is multicast sockets. If two sockets are bound to the same interface and port and are members of the same multicast group, data will be delivered to both sockets, rather than an arbitrarily chosen one.
值得注意的是
當埠口被重複綁定,後續發生的配對行為,都是不可預期的
開發者應自行處理分配的問題