2013-06-04 52 views
0

我通過套接字發送序列化的對象。問題是當我只發送一個字符串(消息)時,我得到了標題中提到的這個錯誤。因此,這裏是類創建套接字對象:我得到java.lang.ClassCastException,但我發送對象,而不是字符串

package Pinger; 

import java.io.*; 
import java.util.Vector; 

public class ChatMessage implements Serializable { 

protected static final long serialVersionUID = 1112122200L; 

static final int WHOISIN = 0, MESSAGE = 1, LOGOUT = 2, JOB = 3; 
private int type,frequency,maxScans,NUMTHREADS,ttl; 
Vector <String> IPS; 
private String message; 

// constructor 
ChatMessage(int type, String message) { 
    this.type = type; 
    this.message = message; 
} 
ChatMessage (int type, int frequency, Vector <String> IPS, int maxScans, int NUMTHREADS, int ttl){ 
    this.type=type; 
    this.frequency=frequency; 
    this.IPS=IPS; 
    this.maxScans=maxScans; 
    this.NUMTHREADS=NUMTHREADS; 
    this.ttl=ttl; 
} 

// getters 
    . 
    . 
    . 

    } 

該類creazes將通過套接字來發送序列化對象。問題是當我發送字符串消息(該字符串被傳遞給ChatMessage類)時,我得到錯誤,Java無法從字符串轉換爲ChatMessage。另外我會給你Client和ClientGUI類,爲你提供你需要了解我的代碼的全部內容。我真的不知道錯誤在哪裏。你們可以幫我嗎?最好的祝福。

package Pinger; 

import java.net.*; 
import java.io.*; 
import java.util.*; 
public class Client { 

// for I/O 
private ObjectInputStream sInput;  // to read from the socket 
private ObjectOutputStream sOutput;  // to write on the socket 
private Socket socket; 

// if I use a GUI or not 
private ClientGUI cg; 

// the server, the port and the username 
private String server, username; 
private int port; 

/* 
* Constructor called by console mode 
* server: the server address 
* port: the port number 
* username: the username 
*/ 
Client(String server, int port, String username) { 
    // which calls the common constructor with the GUI set to null 
    this(server, port, username, null); 
} 

/* 
* Constructor call when used from a GUI 
* in console mode the ClienGUI parameter is null 
*/ 
Client(String server, int port, String username, ClientGUI cg) { 
    this.server = server; 
    this.port = port; 
    this.username = username; 
    // save if we are in GUI mode or not 
    this.cg = cg; 
} 

/* 
* To start the dialog 
*/ 
public boolean start() { 
    // try to connect to the server 
    try { 
     socket = new Socket(server, port); 
    } 
    // if it failed not much I can so 
    catch(Exception ec) { 
     display("Error connecting to server:" + ec); 
     return false; 
    } 

    String msg = "Connection accepted " + socket.getInetAddress() + ":" + socket.getPort(); 
    display(msg); 

    /* Creating both Data Stream */ 
    try 
    { 
     sInput = new ObjectInputStream(socket.getInputStream()); 
     sOutput = new ObjectOutputStream(socket.getOutputStream()); 
    } 
    catch (IOException eIO) { 
     display("Exception creating new Input/output Streams: " + eIO); 
     return false; 
    } 
    new ListenFromServer().start(); 
    try 
    { 
     sOutput.writeObject(username); 
    } 
    catch (IOException eIO) { 
     display("Exception doing login : " + eIO); 
     disconnect(); 
     return false; 
    } 
    // success we inform the caller that it worked 
    return true; 
} 

/* 
* To send a message to the console or the GUI 
*/ 
private void display(String msg) { 
    if(cg == null) 
     System.out.println(msg);  // println in console mode 
    else 
     cg.append(msg + "\n");  // append to the ClientGUI JTextArea (or whatever) 
} 

/* 
* To send a message to the server 
*/ 
void sendMessage(ChatMessage msg) { 
    try { 
     System.out.println(msg); 
     sOutput.writeObject(msg); 
    } 
    catch(IOException e) { 
     display("Exception writing to server: " + e); 
    } 
} 

/* 
* When something goes wrong 
* Close the Input/Output streams and disconnect not much to do in the catch clause 
*/ 
private void disconnect() { 
    try { 
     if(sInput != null) sInput.close(); 
    } 
    catch(Exception e) {} // not much else I can do 
    try { 
     if(sOutput != null) sOutput.close(); 
    } 
    catch(Exception e) {} // not much else I can do 
    try{ 
     if(socket != null) socket.close(); 
    } 
    catch(Exception e) {} // not much else I can do 

    // inform the GUI 
    if(cg != null) 
     cg.connectionFailed(); 

} 
class ListenFromServer extends Thread { 

    public void run() { 
     while(true) { 
      try { 
       ChatMessage msg = (ChatMessage) sInput.readObject(); 
       //if (nesto instanceof String) 
       //msg = (String) sInput.readObject(); 
       //} 
       // if console mode print the message and add back the prompt 
       if(cg == null) { 
        System.out.println(msg.getMessage()); 
        System.out.print("> "); 
       } 
       else { 
        cg.append(msg.getMessage()); 
       } 
      } 
      catch(IOException e) { 
       display("Server has close the connection: " + e); 
       if(cg != null) 
        cg.connectionFailed(); 
       break; 
      } 
      // can't happen with a String object but need the catch anyhow 
      catch(ClassNotFoundException e2) { 
      } 
     } 
    } 
} 
} 

而且這裏是類客戶端GUI類:

package Pinger; 

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.*; 
import java.net.InetAddress; 
import java.net.UnknownHostException; 


/* 
* The Client with its GUI 
*/ 
public class ClientGUI extends JFrame implements ActionListener { 

private static final long serialVersionUID = 1L; 
// will first hold "Username:", later on "Enter message" 
private JLabel label; 
// to hold the Username and later on the messages 
private JTextField tf; 
// to hold the server address an the port number 
private JTextField tfServer, tfPort; 
// to Logout and get the list of the users 
private JButton login, logout, whoIsIn; 
// for the chat room 
private JTextArea ta; 
// if it is for connection 
private boolean connected; 
// the Client object 
private Client client; 
// the default port number 
private int defaultPort; 
private String defaultHost; 
InetAddress ComputerIP; 

// Constructor connection receiving a socket number 
ClientGUI(String host, int port) throws UnknownHostException { 

    super("Chat Client"); 
    defaultPort = port; 
    defaultHost = host; 

    // The NorthPanel with: 
    JPanel northPanel = new JPanel(new GridLayout(3,1)); 
    // the server name anmd the port number 
    JPanel serverAndPort = new JPanel(new GridLayout(1,5, 1, 3)); 
    // the two JTextField with default value for server address and port number 
    tfServer = new JTextField(host); 
    tfPort = new JTextField("" + port); 
    tfPort.setHorizontalAlignment(SwingConstants.RIGHT); 

    serverAndPort.add(new JLabel("Server Address: ")); 
    serverAndPort.add(tfServer); 
    serverAndPort.add(new JLabel("Port Number: ")); 
    serverAndPort.add(tfPort); 
    serverAndPort.add(new JLabel("")); 
    // adds the Server an port field to the GUI 
    northPanel.add(serverAndPort); 

    // the Label and the TextField 
    ComputerIP = InetAddress.getLocalHost(); 
    label = new JLabel("Enter your username below", SwingConstants.CENTER); 
    northPanel.add(label); 
    tf = new JTextField(ComputerIP.toString()); 
    tf.setBackground(Color.WHITE); 
    northPanel.add(tf); 
    add(northPanel, BorderLayout.NORTH); 

    // The CenterPanel which is the chat room 
    ta = new JTextArea("Clients logs\n", 80, 80); 
    JPanel centerPanel = new JPanel(new GridLayout(1,1)); 
    centerPanel.add(new JScrollPane(ta)); 
    ta.setEditable(false); 
    add(centerPanel, BorderLayout.CENTER); 

    // the 3 buttons 
    login = new JButton("Login"); 
    login.addActionListener(this); 
    logout = new JButton("Logout"); 
    logout.addActionListener(this); 
    logout.setEnabled(false);  // you have to login before being able to logout 
    whoIsIn = new JButton("Who is in"); 
    whoIsIn.addActionListener(this); 
    whoIsIn.setEnabled(false);  // you have to login before being able to Who is in 

    JPanel southPanel = new JPanel(); 
    southPanel.add(login); 
    southPanel.add(logout); 
    southPanel.add(whoIsIn); 
    add(southPanel, BorderLayout.SOUTH); 

    setDefaultCloseOperation(EXIT_ON_CLOSE); 
    setSize(600, 600); 
    setVisible(true); 
    tf.requestFocus(); 

} 

// called by the Client to append text in the TextArea 
void append(String str) { 
    ta.append(str); 
    ta.setCaretPosition(ta.getText().length() - 1); 
} 
// called by the GUI is the connection failed 
// we reset our buttons, label, textfield 
void connectionFailed() { 
    login.setEnabled(true); 
    logout.setEnabled(false); 
    whoIsIn.setEnabled(false); 
    InetAddress localIP = null; 
    label.setText("Enter your username below"); 
    try { 
     localIP=InetAddress.getLocalHost(); 
    } catch (UnknownHostException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    tf.setText(localIP.getHostAddress().toString()); 
    // reset port number and host name as a construction time 
    tfPort.setText("" + defaultPort); 
    tfServer.setText(defaultHost); 
    // let the user change them 
    tfServer.setEditable(false); 
    tfPort.setEditable(false); 
    // don't react to a <CR> after the username 
    tf.removeActionListener(this); 
    connected = false; 
} 

/* 
* Button or JTextField clicked 
*/ 
public void actionPerformed(ActionEvent e) { 
    Object o = e.getSource(); 
    // if it is the Logout button 
    if(o == logout) { 
     client.sendMessage(new ChatMessage(ChatMessage.LOGOUT, "")); 
     return; 
    } 
    // if it the who is in button 
    if(o == whoIsIn) { 
     client.sendMessage(new ChatMessage(ChatMessage.WHOISIN, ""));    
     return; 
    } 

    // ok it is coming from the JTextField 
    if(connected) { 
     // just have to send the message 
     client.sendMessage(new ChatMessage(ChatMessage.MESSAGE, tf.getText()));    
     tf.setText(""); 
     return; 
    } 


    if(o == login) { 
     // ok it is a connection request 
     String username = tf.getText().trim(); 
     // empty username ignore it 
     if(username.length() == 0) 
      return; 
     // empty serverAddress ignore it 
     String server = tfServer.getText().trim(); 
     if(server.length() == 0) 
      return; 
     // empty or invalid port numer, ignore it 
     String portNumber = tfPort.getText().trim(); 
     if(portNumber.length() == 0) 
      return; 
     int port = 0; 
     try { 
      port = Integer.parseInt(portNumber); 
     } 
     catch(Exception en) { 
      return; // nothing I can do if port number is not valid 
     } 

     // try creating a new Client with GUI 
     client = new Client(server, port, username, this); 
     // test if we can start the Client 
     if(!client.start()) 
      return; 
     tf.setText(""); 
     label.setText("Enter your message below"); 
     connected = true; 

     // disable login button 
     login.setEnabled(false); 
     // enable the 2 buttons 
     logout.setEnabled(true); 
     whoIsIn.setEnabled(true); 
     // disable the Server and Port JTextField 
     tfServer.setEditable(false); 
     tfPort.setEditable(false); 
     // Action listener for when the user enter a message 
     tf.addActionListener(this); 
    } 

} 

// to start the whole thing the server 
public static void main(String[] args) throws UnknownHostException { 
    new ClientGUI("localhost", 6000); 
} 

} 

編輯1:增加了厚望堆棧跟蹤

Exception in thread "Thread-2" java.lang.ClassCastException: java.lang.String cannot be 
cast to Pinger.ChatMessage 
    at Pinger.Client$ListenFromServer.run(Client.java:143) 
+1

請發佈異常stacktrace –

+0

添加異常堆棧跟蹤。感謝您讓我知道。 – ZhiZha

+0

所以你發送一個'String'並試圖把它作爲一個'ChatMessage'來讀取。太本地化了。 – EJP

回答

1

這個怎麼樣:

sOutput.writeObject(username); 

的第一件事你發送到服務器是String和在服務器端你假設你得到一個ChatMessage

+0

這是我發送字符串的唯一時間。另外當我提交消息(又名寫它併發送它)我得到錯誤。當客戶端連接並且該部分工作正常時,用戶名將被廣播。我會嘗試改變這個...將讓你知道 – ZhiZha

+0

我添加到我的代碼程序發送SendMessage對象,而不是字符串,我仍然有同樣的錯誤。 – ZhiZha

+0

嘗試不要在需要分析和幫助時發佈摘要。 「我添加到我的代碼中,程序發送SendMessage對象而不是String」並不完全告訴我們你做了什麼;識別帖子中的行併發布你替換的代碼,或類似的東西。 – arcy

0

對不起,你打擾你的傢伙。問題出現在我沒有在這裏顯示的服務器類(我的壞)。我通過套接字發送了ChatMessage對象的String。這就是我得到錯誤的原因。我沒有注意到,早些時候......抱歉,請花時間。問題出在服務器類中,它向所有客戶端廣播消息。 ObjectInputStream被轉換爲ChatMessage()的String insted。再多次抱歉打擾你...真的是我的壞...

相關問題