2014-01-24 82 views
1

我想從線程連接到遠程服務器並繼續發送字符串。如果連接被拒絕,線程應該繼續輪詢端口直到服務器重新啓動。我該如何處理這個異常並讓我的線程崩潰?服務器可能不會長時間運行,但線程應無限期地運行。從輪詢線程連接到遠程端口(服務器)

public void SendMessage(String message){ 
    try { 
     socket = new Socket(actuatorAddress, destPort.get()); 
     outToServer = socket.getOutputStream(); 
     out = new DataOutputStream(outToServer); 
     out.flush(); 
     out.write(message.getBytes()); 
    } catch (IOException ex) { 
     System.out.println(ex.getMessage()); 
    } catch (Exception e) { 
     System.out.println(e.getMessage()); 
    } 
} 

我改變了一部分代碼如下。首次調用Connect函數,然後通過線程調用Send Message函數。添加到重新連接的延遲有助於減少由於連接到非現有服務器而導致的時滯。仍然認爲對基本問題可能有更好的解決方案。

public boolean ConnectToActuator() { 
    try { 
     if(actuatorAddress.isReachable(2000)){ 
      socket = new Socket(); 
      socket.setPerformancePreferences(1, 2, 0); 
      socket.setTcpNoDelay(false); 
      socket.setSendBufferSize(32); 
      socket.connect(new InetSocketAddress(actuatorAddress, destPort.get())); 
      outToServer = socket.getOutputStream(); 
      out = new DataOutputStream(outToServer); 
      connected = true; 
      disconnectedTimeout = 0; 
     } 
    }catch (ConnectException e) { 
     // TODO Auto-generated catch block 
     System.out.println(e.getMessage()); 
    }catch (IOException ex) { 
     connected = false; 
     System.out.println(ex.getMessage()); 
    } 
    return connected; 
} 

public boolean SendToActuator(String message) { 
    if(connected == false){ //socket.isOutputShutdown() 
     disconnectedTimeout++; 
     if(disconnectedTimeout>20){ 
      disconnectedTimeout = 0; 
      ConnectToActuator(); 
     } else { 
      return connected; 
     } 
    } 
    try { 
     out.flush(); 
     out.writeBytes(message); 
     disconnectedTimeout = 0; 
     connected = true; 
    } catch (UnknownHostException uhe) { 
     connected = false; 
     System.out.println(uhe.getMessage()); 
    } catch (IOException ioe) { 
     connected = false; 
     System.out.println(ioe.getMessage()); 
    } 
    return connected; 
} 
+0

以分鐘計,「長時間」意味着什麼?此外,您的代碼的目標是什麼:您是在嘗試測試服務是否已啓動,或者確信即使您不知道服務何時可用,最終還是會發送該消息?你是否在意偶爾有些信息會丟失?或者你需要確定他們都收到了? – TreyE

+0

目標是在網絡中連接大約10臺服務器,從該線程讀取消息。服務器可能會斷開幾分鐘甚至幾小時,或者它可能會被取出網絡。但我仍然希望該任務能夠繼續運行並將消息發送給其他連接的服務器。消息的丟失不是問題。 – rohittheozzy

+0

基本上我想處理連接拒絕異常。或者,如果我能夠在創建套接字之前檢查連接是否會被拒絕,那麼更好。 – rohittheozzy

回答

0

僞:

while(true){ 
    if(connect()) DoClientConnectedStuff(); 
    sleep(reconnectTimeout); 
}; 
-1

請嘗試更改下方。如果您的連接拒絕它將等待2s(2000ms),然後再次嘗試連接服務器。如果連接成功,它將採用outputstream,在while循環中寫入數據並刷新數據。

public void createSocketConnection() throws IOException 
{  
    socket = new Socket(actuatorAddress, destPort.get()); 
    if(socket!=null) 
     { 
      outToServer = socket.getOutputStream(); 
      out = new DataOutputStream(outToServer); 
     } 

} 

public void SendMessage(String message){ 
    boolean isRunning=false; 
    try 
    { 
     createSocketConnection(); 
     isRunning=true; 
     while(isRunning) 
     { 
      out.write(message.getBytes()); 
      out.flush(); 
     } 
    } catch (java.net.ConnectException conExcp) { 
     System.out.println(ex.getMessage()); 
     try{ 
      Thread.sleep(2000); 
     }catch(Exception ee){} 
    } 
    catch (IOException ex) { 
     System.out.println(ex.getMessage()); 

    } 
} 
+0

'socket'在你測試它的品脫時不可能爲null。你不花費套接字。此代碼不會重試任何內容。 -1 – EJP

1

鑑於以下約束的評論:

  • 嘗試將郵件發送到10臺服務器中的一個。
  • 如果沒有服務器可用於接收消息,請丟棄該消息。

你真正想要做的是:通過服務器的地址的列表

  1. 迭代
  2. 嘗試發送消息給他們每個人
  3. 跳出循環的時候了,如果成功
  4. 捕獲連接失敗的任何錯誤並嘗試下一臺服務器

下面是一個將通過該場景運行的示例類。

import java.io.DataOutputStream; 
import java.io.OutputStream; 
import java.net.Socket; 

public class MessageSender { 
    private static final Integer destPort = 1234; 

    private static final String[] serverAddresses = { 
    "address1", 
    "address2", 
    "address3" // Etc.... 
    }; 

    public Boolean SendMessage(String message) { 
    Boolean messageSentSuccessfully = false; 
    for (String addy : serverAddresses) { 
     messageSentSuccessfully = SendMessageToServer(addy, message); 
     if (messageSentSuccessfully) { 
     break; 
     } 
    } 
    return messageSentSuccessfully; 
    } 

    private Boolean SendMessageToServer(String serverAddress, String message) { 
    Boolean messageSent = false; 
    try { 
     Socket dataSocket = new Socket(serverAddress, destPort); 
     OutputStream outToServer = dataSocket.getOutputStream(); 
     DataOutputStream out = new DataOutputStream(outToServer); 
     out.write(message.getBytes()); 
     out.flush(); 
     messageSent = true; 
    } catch (Exception e) { 
     System.out.println(e); 
    } 
    return messageSent; 
    } 
} 

希望有幫助。

+0

謝謝TreyE。我嘗試通過使用InetSocketAddress(actuatorAddress,destPort.get())。getAddress()。isReachable(timeout)來檢查遠程服務器是否可用,但它只檢查遠程IP是否可到達,而不檢查特定端口是否可到達。 – rohittheozzy

+0

問題是,你真的不在乎服務器是否可用,你只是在乎你是否可以發送消息。所以你不妨嘗試發送消息。 – TreyE