我通过套接字发送序列化对象。问题是当我只发送一个字符串(消息)时,我在标题上提到了这个错误。所以这里是创建套接字对象的类:
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
.
.
.
}
此类创建可通过套接字发送的可序列化对象。问题是当我发送字符串消息(该字符串传递给ChatMessage类)时,我收到了java无法从String转换为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)
答案 0 :(得分:1)
这个怎么样:
sOutput.writeObject(username);
您发送到服务器的第一件事是String
,而在服务器端,您假设您是ChatMessage
。
答案 1 :(得分:0)
很抱歉打扰你的人。问题在于我没有在这里展示的服务器类(我的坏)。我通过socket发送了对ChatMessage对象的String insted。这就是我收到错误的原因。我之前没有注意到......抱歉花时间。问题出在Server类中,它向所有客户端广播消息。 ObjectInputStream被转换为ChatMessage()的String insted。再一次抱歉打扰你...真的是我的坏......