我嘗試玩插座了一下。爲此,我編寫了非常簡單的「客戶端」和「服務器」應用程序。爲什麼服務器死亡時套接字不會死掉?爲什麼當服務器還活着時,套接字就會死掉?
客戶:
import java.net.*;
public class client {
public static void main(String[] args) throws Exception {
InetAddress localhost = InetAddress.getLocalHost();
System.out.println("before");
Socket clientSideSocket = null;
try {
clientSideSocket = new Socket(localhost,12345,localhost,54321);
} catch (ConnectException e) {
System.out.println("Connection Refused");
}
System.out.println("after");
if (clientSideSocket != null) {
clientSideSocket.close();
}
}
}
服務器:
import java.net.*;
public class server {
public static void main(String[] args) throws Exception {
ServerSocket listener = new ServerSocket(12345);
while (true) {
Socket serverSideSocket = listener.accept();
System.out.println("A client-request is accepted.");
}
}
}
而且我發現我無法解釋一個問題:
我啓動服務器,比我開始一個客戶。連接成功建立(客戶端停止運行並且服務器正在運行)。然後關閉服務器並在一秒鐘內重新啓動。之後,我啓動一個客戶端,並寫入「連接拒絕」。在我看來,服務器「記住」舊連接,並不想打開第二個連接兩次。但我不明白如何可能。因爲我殺了以前的服務器,並開始一個新的!
我沒有立即啓動服務器後,前一個被殺死(我等待20秒)。在這種情況下,服務器將「忘記」以前服務器的套接字並接受來自客戶端的請求。
我啓動服務器,然後啓動客戶端。建立連接(服務器寫入:「客戶機請求被接受」)。然後我等一會兒,然後再次啓動客戶端。而服務器(它一直運行)再次接受請求!爲什麼?服務器不應該接受來自同一客戶端的請求 - IP和客戶端端口,但它確實!
耶,我知道有很多客戶端可以連接到服務器扔在同一個服務器端口。但客戶端應該連接不同的客戶端IP和/或不同的客戶端端口。服務器無法接受來自同一客戶端的第二個連接 - IP和客戶端端口。是的,在我的情況下,我關閉客戶端的套接字,但服務器保持打開此套接字。所以,根據我的理解,服務器不應該允許使用已經佔用的客戶端IP端口號來打開新的套接字。 – Roman 2010-03-17 13:18:45
您保持java Socket打開。操作系統將收到關於連接已關閉的信息,將它的內部句柄標記爲java套接字稱爲關閉的信息,並且將愉快地接受來自同一源端口的新連接,並在接受它時將該套接字綁定到新的Java套接字。您現有的非關閉Java套接字將不會再引用任何打開的套接字。 – nos 2010-03-17 13:23:34
@nos,我保持從一側(服務器端)打開套接字,並從客戶端關閉。你是否說服務器會以某種方式注意到客戶端關閉了它的socket端,結果服務器將關閉他的socket端,並接受來自位於舊IP和舊端口上的客戶端的新請求? – Roman 2010-03-17 13:30:38