代码:
public void showConnectDialog(){ ConnectDialog connectDialog = new ConnectDialog ); connectDialog.setVisible(true); //直到这里,代码运行 while(!connectDialog.getConnected()){}; //下一行只在debug 中运行JOptionPane.showMessageDialog(connectDialog,Connected,Connected,JOptionPane.INFORMATION_MESSAGE); }连接器(尽快启动(作为线程)因为用户在对话框中点击连接):
私有类ServerConnector实现ActionListener,Runnable { @Override public void actionPerformed(ActionEvent e){ if(!IP_field.getText()。equals()){ if(!isConnecting){ new Thread(new ServerConnector(),ServerConnector)。start(); } } else { JOptionPane.showMessageDialog(dialog,输入IP地址,输入IP, JOptionPane.WARNING_MESSAGE); } } @Override public void run(){ try { setConnecting真正); Socket socket = connect(); if(socket!= null){ ObjectOutputStream oOut = new ObjectOutputStream(socket.getOutputStream()); ObjectInputStream oIn = new ObjectInputStream(socket.getInputStream()); if(login(oOut,oIn)){ isConnected = true; setConnecting(false); } else { socket.close(); } setConnecting(false); } } catch(RSPException e){ e.printStackTrace(); System.exit(1); } catch(异常e){ //如果发生异常,setConnecting()将为true。这个 //不好,所以它必须设置为false e.printStackTrace(); setConnecting(false); } } 私有布尔登录(ObjectOutputStream oOut,ObjectInputStream oIn) throws ClassNotFoundException,IOException,RSPException { //发送登录请求动作: oOut.writeObject(new LoginAction(ActionSender.CLIENT,getID(), getPassword())); Object obj = oIn.readObject(); if(obj instanceof LoginActionResult){ LoginActionResult result =(LoginActionResult)obj; if(result.getResult()== LoginResults.SUCCES){ return true; } else if(result.getResult()== LoginResults.FAIL_ON_ID){ JOptionPane.showMessageDialog(dialog,Invalid password or ID,无法登录, JOptionPane.ERROR_MESSAGE); 返回false; } else if(result.getResult()== LoginResults.FAIL_ON_PASSWORD){ JOptionPane.showMessageDialog(dialog,Invalid password or ID,无法登录, JOptionPane.ERROR_MESSAGE); 返回false; } else if(result.getResult()== LoginResults.SERVER_FULL){ JOptionPane.showMessageDialog(dialog,无法连接:\ n+ 服务器已满,无法连接, JOptionPane.WARNING_MESSAGE); 返回false; } else { return false; } } else { System.out.println(obj); 抛出新的RSPException(服务器不遵循协议); } } private void setConnecting(布尔连接){ if(连接){ SwingUtilities.invokeLater (new Runnable(){ @Override public void run(){ connectButton.setEnabled(false); } }); SwingUtilities.invokeLater(new Runnable(){ @Override public void run(){ connectButton.setText(Connecting ...); } }); } else { SwingUtilities.invokeLater(new Runnable(){ @Override public void run(){ connectButton.setText(Connect); } }); SwingUtilities.invokeLater(new Runnable(){ @Override public void run(){ connectButton.setEnabled(true); } }); } isConnecting =连接; } private String getAddressFromTextField(){ return IP_field.getText(); } private InetAddress getInetAddress(String fullAddress){ try { if(fullAddress.contains(:)){ String [] splitAddress = fullAddress.split(:); return InetAddress.getByName(splitAddress [0]); } else {返回InetAddress.getByName(fullAddress); } } catch(UnknownHostException e){ return null; } } private int getPort(String fullAddress){ try { String [] splittedAddress = fullAddress 。分裂(:); return Integer.valueOf(splittedAddress [1]); } catch(NumberFormatException ex){ return -1; } catch(NullPointerException | ArrayIndexOutOfBoundsException | PatternSyntaxException ex){ //返回默认端口值:25566,因为没有给出端口 return 25566; } } @SuppressWarnings(resource) private Socket connect(){ Socket socket =空值; InetAddress address = null; if((address = getInetAddress(getAddressFromTextField()))== null){ return null; } int port = getPort(getAddressFromTextField()); try { socket = new Socket(address,port); } catch(ConnectException e){ Socket retrySocket = null; if((retrySocket = retryConnect(address,port))== null){ JOptionPane.showMessageDialog(dialog,Connection timed out,Failed to connect , JOptionPane.ERROR_MESSAGE); setConnecting(false); } else { socket = retrySocket; } } catch(IOException e){ e.printStackTrace(); } return socket; } private Socket retryConnect(InetAddress address,int port){ Thread waitThread = new Thread(new Runnable(){ @Override public void run(){ try { //等待15(000)(milli)秒,然后停止 //尝试连接 //一秒(1000毫秒)用于调试和测试 Thread.sleep(1000); } catch(InterruptedException e){ e .printStackTrace(); } } }); waitThread.start(); while(waitThread.isAlive()){ try { return new Socket(address,port); } catch(ConnectException e){ //什么都不做,会重新尝试连接。 } catch(IOException e){ e.printStackTrace(); } } 返回null; } private String getID(){ return ID_field.getText(); } private String getPassword(){ if(getID()。equals(master)){ returnmasterPassword } else { return new String(passwordField.getPassword()); } } }$一旦连接到服务器,b $ b
getConnected()返回 true 。连接器在单独的线程上运行。
编辑:我试图将代码放在 getConnected() / code>同时阻止,然后它工作。为什么它不工作呢?
解决方案我有同样的问题,但有一些更多的规范。该代码在32位工作正常,但是我在64位中出现了这个问题(我使用本机库,所以我需要维护两者)。
我发现的解决方案是添加Thread.sleep()在while循环中。我不知道为什么它的工作,所以你的猜测是一样好我的。
更好的解决方案可能会实现一个观察者模式,而不是有无限循环。但是这需要一些重新分解。
I'm really confused by this: some of my code is not working when i run my program normally in eclipse, but it does wok when i run through each step separately using the debug mode.
Code:
public void showConnectDialog() { ConnectDialog connectDialog = new ConnectDialog(); connectDialog.setVisible(true); //Until here, code runs while(! connectDialog.getConnected()) {}; //The next line does only run in debug JOptionPane.showMessageDialog(connectDialog, "Connected", "Connected", JOptionPane.INFORMATION_MESSAGE); }The connector (is started (as a thread) as soon as the user hits 'connect' in the dialog):
private class ServerConnector implements ActionListener, Runnable { @Override public void actionPerformed(ActionEvent e) { if (! IP_field.getText().equals("")) { if (! isConnecting) { new Thread(new ServerConnector(), "ServerConnector").start(); } } else { JOptionPane.showMessageDialog(dialog, "Enter an IP address", "Enter IP", JOptionPane.WARNING_MESSAGE); } } @Override public void run() { try { setConnecting(true); Socket socket = connect(); if (socket != null) { ObjectOutputStream oOut = new ObjectOutputStream(socket.getOutputStream()); ObjectInputStream oIn = new ObjectInputStream(socket.getInputStream()); if (login(oOut, oIn)) { isConnected = true; setConnecting(false); } else { socket.close(); } setConnecting(false); } } catch (RSPException e) { e.printStackTrace(); System.exit(1); } catch (Exception e) { //If an exception occurs, setConnecting() will be true. This //not good, so it has to be set to false e.printStackTrace(); setConnecting(false); } } private boolean login(ObjectOutputStream oOut, ObjectInputStream oIn) throws ClassNotFoundException, IOException, RSPException { //Send login request action: oOut.writeObject(new LoginAction(ActionSender.CLIENT, getID(), getPassword())); Object obj = oIn.readObject(); if (obj instanceof LoginActionResult) { LoginActionResult result = (LoginActionResult) obj; if (result.getResult() == LoginResults.SUCCES) { return true; } else if (result.getResult() == LoginResults.FAIL_ON_ID) { JOptionPane.showMessageDialog(dialog, "Invalid password or ID", "Can't login", JOptionPane.ERROR_MESSAGE); return false; } else if (result.getResult() == LoginResults.FAIL_ON_PASSWORD) { JOptionPane.showMessageDialog(dialog, "Invalid password or ID", "Can't login", JOptionPane.ERROR_MESSAGE); return false; } else if (result.getResult() == LoginResults.SERVER_FULL) { JOptionPane.showMessageDialog(dialog, "Couldn't connect: \n" + "Server is full", "Failed to connect", JOptionPane.WARNING_MESSAGE); return false; } else { return false; } } else { System.out.println(obj); throw new RSPException("Server is not following the protocol."); } } private void setConnecting(boolean connecting) { if (connecting) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { connectButton.setEnabled(false); } }); SwingUtilities.invokeLater(new Runnable() { @Override public void run() { connectButton.setText("Connecting..."); } }); } else { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { connectButton.setText("Connect"); } }); SwingUtilities.invokeLater(new Runnable() { @Override public void run() { connectButton.setEnabled(true); } }); } isConnecting = connecting; } private String getAddressFromTextField() { return IP_field.getText(); } private InetAddress getInetAddress(String fullAddress) { try { if (fullAddress.contains(":")) { String[] splitAddress = fullAddress.split(":"); return InetAddress.getByName(splitAddress[0]); } else { return InetAddress.getByName(fullAddress); } } catch (UnknownHostException e) { return null; } } private int getPort(String fullAddress) { try { String[] splittedAddress = fullAddress.split(":"); return Integer.valueOf(splittedAddress[1]); } catch (NumberFormatException ex) { return -1; } catch (NullPointerException | ArrayIndexOutOfBoundsException | PatternSyntaxException ex) { //Returning default port value: 25566, because no port was given return 25566; } } @SuppressWarnings("resource") private Socket connect() { Socket socket = null; InetAddress address = null; if ((address = getInetAddress(getAddressFromTextField())) == null) { return null; } int port = getPort(getAddressFromTextField()); try { socket = new Socket(address, port); } catch (ConnectException e ) { Socket retrySocket = null; if ((retrySocket = retryConnect(address, port)) == null) { JOptionPane.showMessageDialog(dialog, "Connection timed out", "Failed to connect", JOptionPane.ERROR_MESSAGE); setConnecting(false); } else { socket = retrySocket; } } catch(IOException e) { e.printStackTrace(); } return socket; } private Socket retryConnect(InetAddress address, int port) { Thread waitThread = new Thread(new Runnable() { @Override public void run() { try { //Will wait 15(000) (milli)seconds before stopping with //trying to connect. //One second (1000 millis) is for debugging and testing Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } }); waitThread.start(); while (waitThread.isAlive()) { try { return new Socket(address, port); } catch (ConnectException e) { //Do nothing, will re-attempt to connect. } catch (IOException e) { e.printStackTrace(); } } return null; } private String getID() { return ID_field.getText(); } private String getPassword() { if (getID().equals("master")) { return "masterPassword"; } else { return new String(passwordField.getPassword()); } } }getConnected() returns true as soon as it's connected to the server. The connector is running on a separate thread.
EDIT: I tried to put code in the getConnected() while block, and then it works. Why does it works then and not else?
解决方案I had the same Problem, but with some more specification. The code was working fine in 32bit but I had this issue in 64bit (I am using native library so I need to maintain both).
The solution I found is to add Thread.sleep() in the while loop. I don't know why it works, so your guess is as good as mine.
A better solution would probably to implement an Observer Pattern instead of having an infinite loop. But that would require some re-factoring.
更多推荐
代码在正常运行时不工作,但在调试(eclipse)中工作
发布评论