2013-03-13 125 views
0

我想從服務器端發送一個對象到客戶端,但我找不到問題。這是我收到的客戶端上的錯誤:使用TCP通過套接字從服務器端發送ArrayList到客戶端

java.io.StreamCorruptedException: invalid type code: 43 
at java.io.ObjectInputStream.readObject0(Unknown Source) 
at java.io.ObjectInputStream.readObject(Unknown Source) 
at connection.MainClient.doAll(MainClient.java:56) 
at connection.TestScreen$2.actionPerformed(TestScreen.java:82) 
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source) 
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source) 
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source) 
at javax.swing.DefaultButtonModel.setPressed(Unknown Source) 
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source) 
at java.awt.Component.processMouseEvent(Unknown Source) 
at javax.swing.JComponent.processMouseEvent(Unknown Source) 
at java.awt.Component.processEvent(Unknown Source) 
at java.awt.Container.processEvent(Unknown Source) 
at java.awt.Component.dispatchEventImpl(Unknown Source) 
at java.awt.Container.dispatchEventImpl(Unknown Source) 
at java.awt.Component.dispatchEvent(Unknown Source) 
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source) 
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source) 
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source) 
at java.awt.Container.dispatchEventImpl(Unknown Source) 
at java.awt.Window.dispatchEventImpl(Unknown Source) 
at java.awt.Component.dispatchEvent(Unknown Source) 
at java.awt.EventQueue.dispatchEventImpl(Unknown Source) 
at java.awt.EventQueue.access$200(Unknown Source) 
at java.awt.EventQueue$3.run(Unknown Source) 
at java.awt.EventQueue$3.run(Unknown Source) 
at java.security.AccessController.doPrivileged(Native Method) 
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source) 
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source) 
at java.awt.EventQueue$4.run(Unknown Source) 
at java.awt.EventQueue$4.run(Unknown Source) 
at java.security.AccessController.doPrivileged(Native Method) 
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source) 
at java.awt.EventQueue.dispatchEvent(Unknown Source) 
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source) 
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) 
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source) 
at java.awt.EventDispatchThread.pumpEvents(Unknown Source) 
at java.awt.EventDispatchThread.pumpEvents(Unknown Source) 
at java.awt.EventDispatchThread.run(Unknown Source) 

這裏下面是服務器端方法: 在無限循環的單獨方法只是從文件中讀取和解析的用戶名和密碼ArrayList的它們是Server類中的實例變量。這裏下面

public void doStuff() throws Exception 
{ 
    ServerSocket serverSocket = new ServerSocket(5001); 
    Socket clientSocket = serverSocket.accept(); 
    PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true); 
    BufferedReader in = new BufferedReader(
      new InputStreamReader(
      clientSocket.getInputStream())); 
    ObjectOutputStream objectOutput = new ObjectOutputStream(clientSocket.getOutputStream()); 
    String inputLine; 
    out.println("Connected"); 
    while(true) 
    { 
     seperate(); 
     while ((inputLine = in.readLine()) != null) 
     { 
      if(inputLine.equalsIgnoreCase("users")) 
       objectOutput.writeObject(getUserNames()); 
      else 
       if(inputLine.equalsIgnoreCase("pass")) 
        objectOutput.writeObject(getPassWords()); 
       else 
        if(inputLine.equalsIgnoreCase("stop")) 
         objectOutput.reset(); 
     } 
    } 
} 

是客戶端從服務器請求的信息:在學習服務器插座和插座,但我想在這裏做到的是這個

public boolean doAll(String name, String pass) throws Exception 
{ 
    try 
    { 
     kkSocket = new Socket("PC", 5001); 
     out = new PrintWriter(kkSocket.getOutputStream(), true); 
     in = new BufferedReader(new InputStreamReader(kkSocket.getInputStream())); 
    } 
    catch (UnknownHostException e) 
    { 
     System.err.println("Don't know about host: PC."); 
     System.exit(1); 
    } 
    catch (IOException e) 
    { 
     System.err.println("Couldn't get I/O for the connection to: PC."); 
     System.exit(1); 
    } 

    ObjectInputStream objectInput = new ObjectInputStream(kkSocket.getInputStream()); 

    out.println("user"); 
    Object obj = objectInput.readObject(); 
    users = (ArrayList<String>)obj; 
    out.println("pass"); 
    obj = objectInput.readObject(); 
    this.pass = (ArrayList<String>)obj; 
    out.println("stop"); 
    objectInput.close(); 
    out.close(); 
    in.close(); 
    kkSocket.close(); 

    if(userIsRegistered(name,pass)) 
     return true; 
    return false; 
} 

我新。當我在另一個類中按下一個按鈕,我這樣做:

MainClient b = new MainClient(); 
login = b.doAll(userField.getText(),passField.getText()); 
Login is obviously a boolean. 

差不多一個登錄系統在服務器cleint在當按下登錄按鈕將調用一個客戶端連接到該服務器,並得到用戶的列表並傳遞存儲在指定目錄中的文本文件中的服務器上。然後,當客戶端收到這些信息時,它會檢查它是否可能是來自我從兩個文本字段獲得的字符串中的用戶,並返回true或false。然後關閉套接字到服務器,它應該保持重新連接每一次?

我的主要問題是你如何解決它一直拋出的錯誤?

+0

類似於http://stackoverflow.com/questions/2393179/streamcorruptedexception-invalid-type-code-ac – Shellum 2013-03-13 17:53:00

+0

@Chuck Norris第一次寫**完美**代碼。蟲子害怕他的迴旋踢,因此他的代碼爲什麼沒有錯誤。 – 2013-03-13 17:58:36

+0

@Chuck Norris錯誤被認爲是一個功能。所有開發人員都需要的功能。 – 2013-03-13 17:59:16

回答

1

代碼的流程如下:

  1. 服務器啓動並等待與客戶端的連接
  2. 服務器接受來自使用serverSocket.accept()客戶端的連接。
  3. 服務器通過out.println("Connected")使用PrintWriter對象向客戶端發送String消息(「已連接」)。
  4. 客戶端閱讀使用ObjectInputStream對象這是導致流不匹配,因此違反了內部一致性checks.That就是爲什麼在客戶side.So而不是使用ObjectInputStream讀取由服務器,你應該發送的普通消息的StreamCorruptedException拋出該消息使用上面創建的BufferedReader對象。
在客戶端代碼

所以應修改爲:

ObjectInputStream objectInput = new ObjectInputStream(kkSocket.getInputStream()); 
String message = in.readLine();//use BufferedReader to read the plain message coming from Server. 
System.out.println("Message from server: "+message); 
out.println("user"); 
Object obj = objectInput.readObject(); 
1

您不能使用帶有字節輸入流的InputStreamReader。它期望來自輸入流的字符/字符串。改爲嘗試ObjectInputStream

只是一個提示:輸入流類型應該在服務器端和客戶端都匹配。你不能混用它們。在您使用ObjectOutputStream的服務器上,因此應在客戶端上使用相應的ObjectInputStream

相關問題