[英]How to set client port number in java?
服務器決定接收客戶端連接后,誰能告訴我如何設置客戶端端口號。 我希望客戶端的端口號應在50000到60000之間。
如果您詢問如何對服務器進行編碼以設置客戶端的端口,那么答案是您不能。 客戶端選擇自己的端口,並且在涉及服務器時該端口已經在使用中。
如果您詢問如何對客戶端進行編碼,以選擇與服務器連接的本地端口,則可以查看Socket
文檔。
如果您未指定端口,則操作系統會根據其臨時端口范圍提供任意端口號。
如果您確實指定了本地端口,例如使用構造函數public Socket(InetAddress address, int port, InetAddress localAddr, int localPort)
則客戶端將嘗試綁定到該本地端口。
但是,如果端口不可用,這將失敗。 我們通常要求操作系統提供臨時端口的原因是為了避免當同一客戶端的兩個實例或套接字保持TIME_WAIT
狀態時出現“使用中的地址”失敗。
沒有任何API可以讓您向OS請求給定范圍內的臨時端口。
最好的辦法是請求一個任意端口,然后循環嘗試,直到獲得所需范圍內的端口:
Socket socket;
do {
socket = new Socket();
socket.bind(null); // null means any local address, ephemeral port
} while (! isInRange(socket.getLocalPort());
socket.connect(...);
這種做法的效率很低; 您可以創建和丟棄任意數量的套接字,然后再踩在可接受的套接字上。 如果您希望的范圍是操作系統臨時范圍的一個適當大小的部分,那么這是一種合理的方法。
或者,您可以遍歷可接受的范圍,捕獲綁定錯誤並重試:
Socket socket = new Socket();
for ( int port = MIN_PORT ; port <= MAX_PORT; port++ )
{
try {
s.bind(new InetSocketAddress(port));
break;
} catch (IllegalArgumentException | IOException e) {
// try the next port
}
// deal with not having found a suitable port
}
socket.connect(...);
這有不同的效率低下,如果客戶端頻繁並發運行,這將變得尤為重要。 您將不斷地在范圍較低端的端口上進行“戰斗”。 如果必須使用此方法,則值得對其進行修改,以至少開始查看范圍內的隨機位置。
如果您這樣做的動機是繞過防火牆規則,請嘗試解決(愚蠢,毫無意義的)防火牆規則。 但是,有些客戶端確實使用了我描述的方法,因為有時防火牆管理員不會放棄。
您需要的構造函數是
public Socket(InetAddress address,
int port,
InetAddress localAddr,
int localPort)
此方法允許您提供特定的源端口。 您可以隨機選擇一個,然后重試(如果已使用)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.