现在我正在使用Client-Server应用程序进行一些工作,例如通过带有运行服务器应用程序的raspberry pi的Java应用程序进行通信。
通过这个我发现了一个问题,我找不到可能的解决方案。使用以下代码我可以连接两次到服务器但在2次连接后它将不再接受任何连接。例如,我第一次启动客户端,它很好地工作。然后我关闭客户端并再次启动它再次工作。但如果我关闭它并第三次启动它,它将什么也不做。服务器不接受连接。我在我的私人网络中尝试使用不同的PC,但从未运行第三个连接。
以下是我在服务器上运行的代码:
public class Receiver {
private final Logger logger = Logger.getLogger(this.getClass().getName());
private ServerSocket serverSocket;
private boolean isRunning;
public Receiver(int port) {
isRunning = true;
try {
serverSocket = new ServerSocket(port);
logger.log(Level.FINER, "start listening at port " + port);
logger.log(Level.FINER, "established successful.");
} catch (IOException e) {
logger.log(Level.SEVERE, "Error while opening socket:\n" + LogUtil.getStackTrace(e));
System.exit(1);
}
}
/**
* server starts to listen at the specific port
*/
public void listenServer() {
logger.log(Level.FINER, "Server is listening");
while (isRunning) {
try {
final Socket clientsocket = serverSocket.accept();
logger.log(Level.FINER, "Server accepted Connection from " + clientsocket.getInetAddress());
new Thread(new Runnable() {
@Override
public void run() {
handleConnection(clientsocket);
}
}).start();
} catch (IOException e) {
logger.log(Level.SEVERE, "Connection with Client failed.");
}
}
}
/**
* handles the given connection
*
* @param clientSocket
* the given client socket for this connection
*/
private void handleConnection(Socket clientSocket) {
ObjectInputStream instream = null;
ObjectOutputStream outstream = null;
try {
outstream = new ObjectOutputStream(clientSocket.getOutputStream());
instream = new ObjectInputStream(clientSocket.getInputStream());
final RequestProcessor processor = new RequestProcessor();
final InetAddress inetAdress = clientSocket.getInetAddress();
logger.log(Level.FINER, "handle connection from " + inetAdress);
Object inob;
while ((inob = instream.readObject()) != null) {
logger.log(Level.FINER, "received Object from " + inetAdress);
final ObjectOutputStream finalOutputStream = outstream;
final Object finalInob = inob;
new Thread() {
public void run() {
setPriority(MAX_PRIORITY);
Object outob;
try {
outob = processor.processObject(finalInob);
logger.log(Level.FINER, "send Respond to: " + inetAdress + " Error: " + (outob instanceof ErrorMessage));
finalOutputStream.writeObject(outob);
finalOutputStream.flush();
} catch (IOException e) {
logger.log(Level.SEVERE, "Connection closed to " + inetAdress);
}
}
}.start();
}
closeConnection(clientSocket, instream, outstream);
} catch (IOException e) {
logger.log(Level.SEVERE, "Connection closed to " + clientSocket.getInetAddress());
} catch (ClassNotFoundException e) {
logger.log(Level.SEVERE, "Connection closed to " + clientSocket.getInetAddress());
} finally {
closeConnection(clientSocket, instream, outstream);
}
}
/**
* closes InputStream, OutputStream and socket
*
* @param socket
* @param instream
* @param outstream
*/
private void closeConnection(Socket socket, InputStream instream, OutputStream outstream) {
this.isRunning = false;
if (instream != null) {
try {
instream.close();
} catch (IOException e) {
}
}
if (outstream != null) {
try {
outstream.close();
} catch (IOException e) {
}
}
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
}
}
logger.log(Level.FINER, "Connection was closed to client " + socket.getInetAddress());
}
/**
* closes all connections and ends the server
*/
public void endAllConnections() {
this.isRunning = false;
if (this.serverSocket != null)
try {
this.serverSocket.close();
} catch (IOException e) {
// do nothing
}
}
}
这是我用来连接这个服务器的客户端代码:
public class SocketConnector implements IConnector {
private final Logger logger = Logger.getLogger(this.getClass().getName());
private Socket s;
private ObjectOutputStream oos;
private ObjectInputStream ois;
/**
* creates a new connection
*
* @param host
* given host
* @param port
* given port
*
* @throws UnknownHostException
* @throws IOException
*/
public SocketConnector(String host, int port) throws UnknownHostException, IOException {
logger.log(Level.FINER, "Establish connection to " + host + ":" + port);
s = new Socket(host, port);
oos = new ObjectOutputStream(s.getOutputStream());
ois = new ObjectInputStream(s.getInputStream());
}
// some methos which use oos and ois.
当有2个客户端连接并断开连接时,有人可能知道为什么服务器不再接受任何连接?我google了很多但没有找到合适的答案:/ 服务器日志表示它甚至不接受新连接。
提前致谢:)
答案 0 :(得分:2)
情况是:
第一次调用final Socket clientsocket = serverSocket.accept();
时,它正在等待第一个客户端。当第一个客户端连接时,将此客户端传递给线程,然后继续第二次调用final Socket clientsocket = serverSocket.accept();
的循环。由于启动线程比进入下一个循环花费的时间更长,isRunning
仍然是true
。在handleConnection(Socket clientSocket)
,您致电closeConnection(clientSocket, instream, outstream);
,将isRunning
设置为false
。这就是重点。当第二个客户端连接时,您还将此客户端传递给另一个线程,然后继续isRunning
为false
的循环,以便终止循环。因此,你无法到达第三个客户。