[英]Java Server - Multiple ports?
我即將對服務器進行編程,但我想知道我的想法是否可行。 我的程序將輸出到多個端口上的多個客戶端 - 每個端口可以被多個客戶端訪問。
通常我會使用線程套接字服務器,但在這種情況下,我需要它為多個端口工作。 我想到的用法是在下面的模糊偽代碼中:
x
y
希望這是有道理的,你可以看到我在做什么。 簡單地說:偵聽選定的端口,根據正在連接的端口創建線程套接字連接。
這是可行的,還是我最終會使用多線程線程套接字服務器?
編輯:更改措辭以更好地反映問題。
單個ServerSocket
實例不可能偵聽多個端口。 您當然可以有多個ServerSocket
。 但是,正如您已經知道的, ServerSocket.accept
阻塞。
您可以使用的是ServerSocketChannel
。 它們以類似的方式使用,但不會阻塞。
如果在調用ServerSocketChannel.accept
時沒有掛起的連接,則它只返回 null。
您可以與Selector
一起使用,該Selector
接受一組通道並阻塞,直到至少有一個具有掛起的連接。
我不記得如何使用它們的細節,但這個似乎是一個體面的代碼示例。
編輯:這是我自己的例子(偽ish)
Selector selector = Selector.open();
int[] ports = {4000,4001,6000};
for (int port : ports) {
ServerSocketChannel server = ServerSocketChannel.open();
server.configureBlocking(false);
server.socket().bind(new InetSocketAddress(port));
// we are only interested when accept evens occur on this socket
server.register(selector, SelectionKey.OP_ACCEPT);
}
while (selector.isOpen()) {
selector.select();
Set readyKeys = selector.selectedKeys();
Iterator iterator = readyKeys.iterator();
while (iterator.hasNext()) {
SelectionKey key = (SelectionKey) iterator.next();
if (key.isAcceptable()) {
SocketChannel client = server.accept();
Socket socket = client.socket();
// create new thread to deal with connection (closing both socket and client when done)
}
}
}
// tidy up selector and channels
你好,讓我直說吧。 您想要做的是創建一個可以偵聽多個端口的服務器,當您獲得新連接時,您希望能夠知道該連接使用了哪個端口,這是正確的嗎? 好吧,如果是這種情況,您可以使用java.nio
包輕松完成此操作。
我們將使用Selector進行准備選擇,並使用ServerSocketChannel來偵聽傳入的連接。
首先我們需要聲明我們的Selector
。
Selector selector = Selector.open();
現在讓我們創建一個要監聽的端口列表並開始監聽它們。
int ports[] = new int[] { 1234, 4321 };
// loop through each port in our list and bind it to a ServerSocketChannel
for (int port : ports) {
ServerSocketChannel serverChannel = ServerSocketChannel.open();
serverChannel.configureBlocking(false);
serverChannel.socket().bind(new InetSocketAddress(port));
serverChannel.register(selector, SelectionKey.OP_ACCEPT);
}
現在是SelectionKey
處理過程。
while (true) {
selector.select();
Iterator<SelectionKey> selectedKeys = selector.selectedKeys().iterator();
while (selectedKeys.hasNext()) {
SelectionKey selectedKey = selectedKeys.next();
if (selectedKey.isAcceptable()) {
SocketChannel socketChannel = ((ServerSocketChannel) selectedKey.channel()).accept();
socketChannel.configureBlocking(false);
switch (socketChannel.socket().getPort()) {
case 1234:
// handle connection for the first port (1234)
break;
case 4321:
// handle connection for the secon port (4321)
break;
}
} else if (selectedKey.isReadable()) {
// yada yada yada
}
}
}
也許這樣簡單的任務不需要 switch 語句,但它是為了便於閱讀和理解。
請記住,此服務器以非阻塞異步方式設置,因此您執行的所有 I/O 調用都不會阻塞當前線程。 所以不要在SelectionKey
處理過程中啟動任何新線程。
另外,我知道這並不能完全回答您的問題(可能,也可能沒有),但實際上它會讓您了解如何使用java.nio
包來創建可以偵聽的非阻塞異步服務器在多個端口上。
您不能偵聽所有端口,但可以偵聽一組端口。 為您要偵聽的每個端口創建一個ServerSocket
( http://download.oracle.com/javase/6/docs/api/java/net/ServerSocket.html#ServerSocket%28int%29 ),並接受每個端口上的連接.
NIO 應該可以做到這一點,但是我認為沒有充分的理由避免每個偵聽器擁有一個線程,除非您有超過 1K 的端口。
你真的需要多個監聽端口嗎? 在大多數情況下,一個端口應該可以支持所有類型的客戶端並讓客戶端告訴服務器(或服務器確定需要哪種類型的連接)
我不認為您可以收聽所有端口,不。 對於操作系統來說,這將是非常昂貴的,所以這根本不是端口偵聽的工作方式。
如果多個應用程序同時偵聽“所有”端口,網絡子系統應該將傳入的數據包傳送到哪個應用程序呢?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.