2017-09-26 93 views
0

嗨,並提前致謝。Java TCP - 需要客戶端服務器幫助

我目前正在嘗試創建一個客戶端服務器程序,服務器根據來自客戶端的不同請求響應客戶端。

這裏是我想爲先的要求做(這個問題是所有客戶端不同的請求到服務器的相同,所以固定只是這將幫助我解決所有問題):

1)客戶端連接到服務器

2)客戶端發送登錄信息向服務器

3)服務器檢查的有效性

4)服務器發送響應說登錄信息該登錄是成功的。

5)客戶端接收並顯示響應。

這裏是客戶端(第一嘗試塊位於客戶端幀,一個動作偵聽器內的第二一個按鈕的客戶端幀上):

try 
{ 
    mySocket = new Socket("localhost", 2016); 
} 
catch (UnknownHostException e1) 
{ 
    e1.printStackTrace(); 
} 
catch (IOException e1) 
{ 
    e1.printStackTrace(); 
} 

try 
{ 
    DOS = new DataOutputStream(mySocket.getOutputStream()); 
    DOS.writeUTF(txtName.getText() + " " + txtPassword.getText()); 
    DOS.flush(); 
    DOS.close(); 

    DataInputStream DISLog = new DataInputStream(mySocket.getInputStream()); 
    JOptionPane.showMessageDialog(null, DISLog.readLine()); 
} 
catch(IOException e1) 
{ 
    e1.printStackTrace(); 
} 

服務器:

 System.out.println("Waiting for client...."); 
     ServerSocket myServerSocket = new ServerSocket(2016); 
     Socket mySocket = myServerSocket.accept(); 

     myClientHandler = new EZFILEHandler(mySocket); 

     //Log in check 

     DataInputStream DISLog = new DataInputStream(mySocket.getInputStream()); 

     StringTokenizer ST = new StringTokenizer(DISLog.readLine()); 
     String Name = ST.nextToken(); 
     String Password = ST.nextToken(); 

     //DISLog.close(); 

     boolean Found = myClientHandler.matchUser(Name,Password); 

     DataOutputStream DOS = new DataOutputStream(mySocket.getOutputStream()); 

     if (Found == true) 
     { 
      DOS.writeUTF("You are logged in."); 
      DOS.flush(); 
      LoggedIn = true; 
     } 

     if (Found == false) 
     { 
      DOS.writeUTF("You could not log in."); 
      DOS.flush(); 
     } 

下面是在服務器代碼中提到的ClientHandler的代碼:

public EZFILEHandler(Socket newConnectionToClient) 
    { 
     try 
     { 
      mySocket = new Socket("localhost", 2016); 
     } 
     catch(Exception e) 
     { 
      e.printStackTrace(); 
     } 
    } 

運行日上面的代碼會在客戶端的這一行發出Socket is closed異常:DataInputStream DISLog = new DataInputStream(mySocket.getInputStream());,所以我嘗試在客戶端註釋掉以下行:DOS.close();以保持套接字處於打開狀態,但這會導致調用客戶端代碼的按鈕凍結程序並指向這條線,如果我終止程序:JOptionPane.showMessageDialog(null, DISLog.readLine());

所以我的問題是這樣的:我如何允許客戶端和服務器以不同的方式響應對方沒有套接字關閉或jswing凍結不被允許完成處理?

另外,我怎麼可能允許多個客戶端登錄到服務器,並且他們的所有請求仍然安全地處理?

謝謝。

+0

你如何爲服務器和客戶端創建套接字,爲服務器創建服務器套接字...... – Audi

+0

我剛剛添加了我的服務器套接字代碼,供您在編輯中查看。 – Duckman

+0

你對客戶端和服務器都使用單一的類..你的代碼中的coz我看到你正在服務器類中創建客戶端套接字..看看下面的鏈接爲一個簡單的例子..我會推薦使用單獨的課程。 https://systembash.com/a-simple-java-tcp-server-and-tcp-client/ – Audi

回答

0

如果你正在編寫一個Swing程序,你的套接字通信應該在它自己的SwingWorker線程上。

讓我們忽略它,並假裝它只是調試代碼,不打算留下來。

DISLog.readLine()將讀取,直到它到達換行符或輸入流的結尾。服務器執行(說)以下內容:

DOS.writeUTF("You are logged in."); 
DOS.flush(); 

沒有換行符。並且flush()未關閉流;它只是確保發送所有字符,而不是保留在緩衝區中與下一組要發送的字符組合。

Catch-22?對!客戶端正在等待\n,並且服務器正在等待來自客戶端的更多命令。

更改客戶端使用readUTF()

更新看起來你需要更改服務器以使用readUTF()以及。服務器可能沒有通過new StringTokenizer(DISLog.readLine())調用,除非客戶端關閉套接字。

+0

因此,我將\ n添加到包含在writeUTF(現在的:DOS.writeUTF(txtName.getText()+「」+ txtPassword.getText()+「\\ n」);)和I也改變了readLine爲readUTF,但我想出了一個不同的錯誤。它指向新的JOptionPane.showMessageDialog(null,DISLog.readUTF());在客戶端,並說'連接重置'。 – Duckman

+0

不要介意上面的評論,我只是添加了新的更改。 – Duckman

+0

太棒了。有用。非常感謝;) – Duckman