2017-04-14 58 views
0

下面我有我的服務器代碼在這裏:服務器不發送回一個確認信息給客戶

public void startServer() { 
     ServerSocket listener = selectUnusedPortFromRange(1024, 65535); 
     Thread t = new Thread(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        String command = null; 
        while (true) { 
         Socket socket = listener.accept(); 
         System.out.println("Got a connection from: " + socket.getLocalPort()); 
         BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
         command = in.readLine(); 
         System.out.println("GOT HERE"); //Not being printed out 
         if (command != null && !"".equals(command)) { 
          if ("connection".equals(command)) { 
           Writer writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); 
           writer.write("success\n"); 
           writer.flush(); 
          } 
         } 
        } 
       } 
      } 
     } 
     t.start(); 
} 

這是我的客戶端:

public void makeConnection() { 
    try { 
     Socket socket = new Socket(IP, PORT); 
     Writer writer = new PrintWriter(socket.getOutputStream(), true); 
     writer.write("connection\n"); 
     BufferedReader socketRead = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
     String str; 
     while ((str = socketRead.readLine()) != null) { 
      if ("success".equals(str)) { 
       System.out.println("Successfully saved all hosts to: " + listOfHosts.get(i)); 
       socketRead.close(); 
       socket.close(); 
       iStream.close(); 
       writer.close(); 
      } 
     } 
    }catch (Exception e) { 
     System.out.println(e.getMessage()); 
    } 
} 

在客戶端後,我創造我插座連接到服務器我寫入「連接」到套接字的outputStream,並等待服務器迴應確認成功。出於某種原因,連接不會發送到服務器。在服務器System.out.println("Got a connection from: " + socket.getLocalPort());這一行沒有被打印出來。

有沒有什麼問題,我正在做。我無法發現它。當我嘗試連接到我的服務器時,我沒有收到異常。

+0

進行仔細的檢查...你的客戶端是否使用服務器綁定的同一端口?我不知道'selectUnusedPortFromRange()'做了什麼,但我的猜測是它綁定到指定範圍內的一個隨機未使用的端口?確保你的客戶知道它綁定到哪個端口。 – SnakeDoc

+0

@cricket是的,我剛剛注意到並改變了它。那是我的打字錯誤。我已經將其更改爲我的帖子中的正確代碼。 – CapturedTree

+1

看過這個嗎? https://docs.oracle.com/javase/tutorial/networking/sockets/readingWriting.html –

回答

1

1)請確保您爲客戶端和服務器使用相同的端口。他們必須通過同一個端口進行通信。看來你可能正在使用不同的端口。

2)確保你真的開始你的服務器線程。按照上面的代碼,您創建了一個新線程,但從未啓動它。必須在某處調用t.start()

3)如果這是在您的本地機器上,最好使用localhost而不是實際的IP地址。防火牆可能會以不同方式處理您的外部IP

4)使用換行符(如\n)終止您的消息,以便您的BufferedReader可以使用它的readLine()方法。爲了更好的衡量,還需要刷新作者的緩衝區,以防萬一換行符沒有觸發。 writer.flush();

最後,確保在嘗試再次運行代碼之前終止JVM。你的代碼沒有關閉機制來解除服務器與端口的綁定...所以你可能會得到一個異常,告訴你端口和/或地址已經被使用了。如果發生這種情況,請更改端口,或終止在後臺運行的java進程。

這裏是你的代碼,稍作修改後在我的系統上運行。它按照您的預期工作。我試圖儘可能少地改變它以使其在我的系統上運行。一本筆記,我硬編碼的端口號爲服務器和客戶端 - 這不是必需的,這只是便於我與測試:

import java.io.BufferedReader; 
import java.io.BufferedWriter; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.io.OutputStreamWriter; 
import java.io.PrintWriter; 
import java.io.Writer; 
import java.net.ServerSocket; 
import java.net.Socket; 

public class Test { 
    public static void main(String[] args) throws IOException { 
     Test test = new Test(); 
     test.startServer(); 
     test.makeConnection(); 
    } 

    public void startServer() throws IOException { 
     final ServerSocket listener = new ServerSocket(60001); 
     Thread t = new Thread(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        String command = null; 
        while (true) { 
         Socket socket = listener.accept(); 
         System.out.println("Got a connection from: " + socket.getLocalPort()); 
         BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
         command = in.readLine(); 
         System.out.println("GOT HERE"); 
         if (command != null && !"".equals(command)) { 
          if ("connection".equals(command)) { 
           Writer writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); 
           writer.write("success\n"); 
           writer.flush(); 
          } 
         } 
        } 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 
     t.start(); 
    } 

    public void makeConnection() { 
     System.out.println("Making Connection");; 
     try { 
      Socket socket = new Socket("localhost", 60001); 
      Writer writer = new PrintWriter(socket.getOutputStream(), true); 
      writer.write("connection\n"); 
      writer.flush(); 
      BufferedReader socketRead = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
      String str; 
      while ((str = socketRead.readLine()) != null) { 
       if ("success".equals(str)) { 
        System.out.println("Successfully saved all hosts to: "); //+ listOfHosts.get(i)); 
        socketRead.close(); 
        socket.close(); 
        //iStream.close(); 
        writer.close(); 
       } 
      } 
     }catch (Exception e) { 
      System.out.println(e.getMessage()); 
     } 
    } 

} 
+0

OMG非常感謝。數字1被排除,數字2我忘了在我的問題(我的輸入錯誤)中添加't.start()',對此感到遺憾,數字3(沒有防火牆),數字4是主要的東西,你的示例代碼有幫助很多。謝謝!! – CapturedTree

+1

@ 1290很高興你的工作。快樂編碼! :) – SnakeDoc

+0

現在還有一個問題....在我的服務器'writer.write(「success \ n」);'部分沒有被髮送回客戶端。它進入'if(「connection」.equals(command)){}塊,但它不會發回'writer.write(「success \ n」);'。 – CapturedTree

1

我面對完全一樣的問題。我通過使用ACK機制克服了它(這不是我的想法,而是我建議的)。這個想法是,客戶端會向服務器發送請求,並且保持套接字連接處於活動狀態(並且輸出流打開),直到服務器通過相同的通道響應同意的ACK消息。客戶端收到ACK消息後,纔會關閉連接。

下面是服務器的代碼: -

final ServerSocket listener = new ServerSocket(11111); 
    Thread t = new Thread(new Runnable() { 
     @Override 
     public void run() { 
      try { 
       String command = null; 
       while (true) { 
        System.out.println("About to accept"); 
        Socket socket = listener.accept(); 
        System.out.println("Got a connection from: " + socket.getLocalPort()); 
        DataInputStream inputStream = new DataInputStream(socket.getInputStream()); 
        StringBuilder str = new StringBuilder(inputStream.readUTF()); 
        //command = in.readLine(); 
        System.out.println("GOT HERE. Msg received : "+str); 
        if (str != null && !"".equals(str.toString())) { 
         command = str.toString(); 
         if ("connection".equals(command)) { 
          System.out.println("Got connection message"); 
          DataOutputStream outputStream = new DataOutputStream(socket.getOutputStream()); 
          outputStream.writeUTF("connection"); 
          outputStream.close(); 

         } 
        } 
        inputStream.close(); 
        System.out.println("Done"); 
       } 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } finally { 
      } 
     } 
}); 
    t.start(); 

} 

客戶: -

public void makeConnection() { 
    try { 
     System.out.println("In makeConnection"); 
     Socket socket = new Socket("127.0.0.1", 11111); 
     DataOutputStream outputStream = new DataOutputStream(socket.getOutputStream()); 
     outputStream.writeUTF("connection"); 
     InputStream inputStream = socket.getInputStream(); 
     DataInputStream dataInputStream = new DataInputStream(inputStream); 
     StringBuilder str; 
     do { 
      str = new StringBuilder(dataInputStream.readUTF()); 
      } while (!str.toString().equals("connection")); 
     System.out.println("Successfully saved all hosts to: "); 
     outputStream.close(); 
     dataInputStream.close(); 
     socket.close(); 
     outputStream.close(); 
    }catch (Exception e) { 
     System.out.println(e.getMessage()); 
    } 
} 

的調用來啓動程序: -

public void start() throws IOException, InterruptedException { 
    System.out.println("Starting server"); 
    startServer(); 
    Thread.sleep(1000); 
    System.out.println("Starting connection"); 
    makeConnection(); 
} 
相關問題