我在Windows 7 x64上。我正在編寫一個服務器,它爲每個傳入連接打開一個線程 - 線程從連接的輸入流中讀取數據。如果套接字關閉(),read()會阻塞並拋出一個異常。它不 - 只返回-1。如果我沒有關閉客戶端的連接 - 只是讓客戶端終止 - 我得到的連接重置被重視 - 但是如果我關閉()來自客戶端的連接(或者僅僅是客戶端的輸出流)read()在服務器線程中不拋出 - 只返回-1
。該docs是很清楚這個:當我關閉客戶端的套接字時,socket.getInputSteam.read()不會拋出
公共無效的close() 拋出IOException異常
Closes this socket. Any thread currently blocked in an I/O operation upon this socket will throw a SocketException.
幫助
工作代碼:
服務器:
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.logging.Level;
import java.util.logging.Logger;
public class CloseTest {
private int port;
public CloseTest(int port) {
this.port = port;
}
void base_station_activate() {
ServerSocket baseStationListeningSocket=null;
try {
baseStationListeningSocket = new ServerSocket(this.port, 1, InetAddress.getByName("127.0.0.1"));
} catch (IOException ex) {
}
main_server: while (true) {
try {
Socket clientSocket = baseStationListeningSocket.accept();
BaseStationClientHandler ch = new BaseStationClientHandler(clientSocket);
Thread myThread = new Thread(ch);
myThread.start();
} catch (IOException ex) {
System.exit(1);
} // main_server
finally {
// baseStationListeningSocket.close()
}
}
}
public static void main(String args[]){
CloseTest bs = new CloseTest(8082);
bs.base_station_activate();
}
public class BaseStationClientHandler implements Runnable {
private final Socket clientSocket;
private BaseStationClientHandler(Socket clientSocket) {
this.clientSocket = clientSocket;
}
public void run() {
String debug_message = null;
try {
InputStream in = clientSocket.getInputStream();
// read message and respond
String s = "";
char x;
int r;
server: while (true) {
try {
while ((r = in.read()) != (int) '%') {
if (r == -1) {
debug_message = "Stream/socket .closed() - exception not thrown (WHYYYYY ????) by client";
System.out.println(debug_message);
break server;
}
x = (char) r;
s += x;
}
System.out.println(s);
} catch (SocketException socketException) {
System.out.println(socketException.getLocalizedMessage()); // if connection reset (but not if Stream/socket .closed()) read throws !!!!!
debug_message = "socket_reset";
break server;
}
s = "";
} //server
} catch (IOException ex) {
System.out.println("IOexception in client handler - check if thrown by read");
} finally {
try {
clientSocket.close();
} catch (IOException ex) {
}
}
}
}
}
客戶:
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Vector;
public class CloseTestClient {
public CloseTestClient(int port, String ipAddress){
Vector<Socket> connections = new Vector<Socket>();
try {
for(int i=0;i<20;i++){
Socket connection = new Socket(InetAddress.getByName(ipAddress), port);
connections.add(connection);
OutputStream out = connection.getOutputStream();
out.write(("CONNECT#"+(i+1)+"#1%").getBytes());
System.out.println("[CloseTestClient SENT]:"+"CONNECT#"+(i+1)+"#1%");
Thread.sleep(1000); // to be sure the server threads are blocked in the read()
// connection.close(); // if I comment this out I see the connection reset message from the server when this main terminates
// commented it out finally and moved the closing at the end to be sure the server threads are blocked in read()
}
} catch (Exception ex) {
ex.printStackTrace();
}
finally{
// if I comment *for* out I see the "connection_reset" message from the server when this main terminates
for (Socket c : connections){
try{
c.close();
}catch(Exception ex){
}
}
}
}
public static void main(String args[]){
System.out.println("CloseTestClient run !");
new CloseTestClient(8082,"127.0.0.1");
}
}
它們在同一臺計算機上 - 主機是「127.0.0.1」 - 或者您的機器是什麼意思? –
對不起,本意是說在這個例子中的兩個線程是同一過程的一部分。至少我是這樣解釋文檔的。我沒有測試過它。我知道close()不會導致在套接字的另一端拋出異常。 – Neal
你能指點我一些文檔嗎?你的意思是,當一個關閉()來自不同進程的套接字時,沒有異常? –