我写的c/s,socket程序,客户端发送的消息,服务器可以接收到;但是服务器反馈的消息,客户端却接收不到,为什么?
我简化后的程序如下:server端:
import java.net.*;
import java.sql.*;
import java.util.Hashtable;
import java.io.*;public class logRegServer {
private static final long serialVersionUID = 1L;

ServerSocket serverSocket;
final int port=1444; //服务器和客户端监听的默认端口号

//该Hashtable用于记录链接服务器的客户端信息
private Hashtable<Socket,ObjectOutputStream> ht=
new Hashtable<Socket, ObjectOutputStream>(); 

public static void main(String[] args) throws IOException{
new logRegServer();
}

public logRegServer() throws IOException{
Socket clientSocket;

try{
//建立服务器套接字
serverSocket=new ServerSocket(port);

System.out.println("Log and Register Server started at: "+
serverSocket.getInetAddress().getLocalHost()+":"+
//InetAddress.getLocalHost()+":"+
serverSocket.getLocalPort());

while(true){
//服务器监听客户端的链接
clientSocket=serverSocket.accept();
System.out.println("Connection from: "+clientSocket);

//建立客户端的输出数据流
// DataOutputStream outData=new 
// DataOutputStream(clientSocket.getOutputStream());
ObjectOutputStream outData=new ObjectOutputStream(clientSocket.getOutputStream());

//将客户端套接字和客户端对应的输出数据流绑定并添加到Hashtable中记录
ht.put(clientSocket, outData);

//新建立服务器线程,用于处理客户端的请求服务
Thread thread=new Thread(
new serverThread(clientSocket,ht));
thread.start(); //线程开始运行
}
}catch(IOException e){
e.printStackTrace();

}

}class serverThread extends Thread implements Runnable{
private Socket clientSocket;
private Hashtable ht;

public serverThread(Socket clientSocket,Hashtable ht){
this.clientSocket=clientSocket;
this.ht=ht;
}

public void run(){
ObjectInputStream inData;
String logName=""; //用户登录名

try {
//建立客户端输入/输出数据流
inData=new ObjectInputStream(clientSocket.getInputStream()); while(true){
//接受客户端发送来的请求消息

//读取客户端发送来的消息标识
String inStrType=inData.readObject().toString();
System.out.println("消息类型:"+inStrType);

//依据请求消息的起始部分,判断客户端请求服务的内容

if(inStrType.equals("Verify")){ //密码验证
logName=inData.readObject().toString();

try{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
try {
Connection c=DriverManager.getConnection("jdbc:odbc:onlineJudge");
Statement s=c.createStatement();

ObjectOutputStream outData=new
ObjectOutputStream(clientSocket.getOutputStream());

//返回对应用户名的密码
ResultSet rs=s.executeQuery("select password from userInfoTable where userName='shimo'"); /**如果用户存在*/
if(rs.next()){
outData.writeObject(rs.getString("password"));
outData.flush();
}else{
outData.writeObject("UserNotExist@");
outData.flush();
}

outData.close();
//关闭数据库链接
s.close();
c.close();
}catch (SQLException se) { //未找到数据库,捕获异常
while (se != null) {
    String SQLState = se.getSQLState();
    String SQLMessage = se.getMessage();
    System.out.println("Error = "+SQLState);
    System.out.println(SQLMessage);
    se = se.getNextException();
}
}
}catch(ClassNotFoundException e){ //未找到数据源驱动,捕获异常
e.printStackTrace();
}
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
System.out.println("end");
}
} //end run
}class serverThread extends Thread implements Runnable{
private Socket clientSocket;
private Hashtable ht;

public serverThread(Socket clientSocket,Hashtable ht){
this.clientSocket=clientSocket;
this.ht=ht;
}

public void run(){
ObjectInputStream inData;
String logName=""; //用户登录名

try {
//建立客户端输入/输出数据流
inData=new ObjectInputStream(clientSocket.getInputStream()); while(true){
//接受客户端发送来的请求消息

//读取客户端发送来的消息标识
String inStrType=inData.readObject().toString();
System.out.println("消息类型:"+inStrType);

//依据请求消息的起始部分,判断客户端请求服务的内容

if(inStrType.equals("Verify")){ //密码验证
logName=inData.readObject().toString();

try{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
try {
Connection c=DriverManager.getConnection("jdbc:odbc:onlineJudge");
Statement s=c.createStatement();

ObjectOutputStream outData=new
ObjectOutputStream(clientSocket.getOutputStream());

//返回对应用户名的密码
ResultSet rs=s.executeQuery("select password from userInfoTable where userName='shimo'"); /**如果用户存在*/
if(rs.next()){
outData.writeObject(rs.getString("password"));
outData.flush();
}else{
outData.writeObject("UserNotExist@");
outData.flush();
}

outData.close();
//关闭数据库链接
s.close();
c.close();
}catch (SQLException se) { //未找到数据库,捕获异常
while (se != null) {
    String SQLState = se.getSQLState();
    String SQLMessage = se.getMessage();
    System.out.println("Error = "+SQLState);
    System.out.println(SQLMessage);
    se = se.getNextException();
}
}
}catch(ClassNotFoundException e){ //未找到数据源驱动,捕获异常
e.printStackTrace();
}
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
System.out.println("end");
}
} //end run
}客户端:
import javax.swing.*;
import java.io.*;
import java.net.*;public class LogGUI {
static JFrame frame = new JFrame("ACM@ZZU");
private static final long serialVersionUID = 1L;
    private static Socket clientSocket=null;
private static final String host="localhost";
private static final int port=1444;
    
    public LogGUI() throws IOException    {
     try {
clientSocket = new Socket(InetAddress.getByName(host),port);
// clientSocket.setSoLinger(true, 20);
} catch (UnknownHostException e1) {
// TODO Auto-generated catch block
System.out.println("cannot connect the server!");
e1.printStackTrace();
} catch (IOException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}

ObjectInputStream inData=new ObjectInputStream(clientSocket.getInputStream());
ObjectOutputStream outData=new ObjectOutputStream(clientSocket.getOutputStream());

outData.writeObject("Verify");
outData.writeObject("shimo");

String s="";
try {
s = inData.readObject().toString();
System.out.println(s);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
System.out.println("receive from server ERROR!");
e.printStackTrace();
}
    }    public static void main(String[] args) throws IOException {
     new LogGUI();
    }
}谢谢大家!

解决方案 »

  1.   

    帖子,找不到编辑。发的时候忘了标识了。错误为:在客户端接收消息的那个语句上。客户端代码:LogGUI.java报的错误为:
    Exception in thread "main" java.io.StreamCorruptedException: invalid type code: AC
     at java.io.ObjectInputStream.readObject0(Unknown Source)
     at java.io.ObjectInputStream.readObject(Unknown Source)
     at LogGUI.<init>(LogGUI.java:41)
     at LogGUI.main(LogGUI.java:51)
      

  2.   

    可能是你读取操作的文件已经损坏造成的,或是文件对象没有可序列实例化,lz重新序列实例化一下对象。lz可以看下我给别人解决的帖子:http://topic.csdn.net/u/20080405/17/80c2af21-0fa4-431a-bc7a-fec60f028f76.html
      

  3.   

    程序有三个问题如下,帮你修改了一下:
    1. 采用ObjectInputStream和ObjectoutputStream序列化必须实现Serializable接口,即implements Serializable
    2. 在服务器端没有用outData.writeObject()方法
    3. 当客户端发送数据到服务器后,服务器返回数据给客户端,由于客户端没有把监听放在while(ture)的循环中,服务器返回数据会出错,抛出java.net.SocketException: Connection reset异常!
    由于你没有上传数据库,所有用注释把你的连接数据库的代码注释掉了,测试能够运行,仅供参考
    客户端import javax.swing.*;
    import java.io.*;
    import java.net.*;public class LogGUI implements Serializable {
    // static JFrame frame = new JFrame("ACM@ZZU");
    private static final long serialVersionUID = 1L;
    private static Socket clientSocket = null;
    private static final String host = "localhost";
    private static final int port = 1444; public LogGUI() throws IOException {
    try {
    clientSocket = new Socket(InetAddress.getByName(host), port);
    // clientSocket.setSoLinger(true, 20);
    } catch (UnknownHostException e1) {
    // TODO Auto-generated catch block
    System.out.println("cannot connect the server!");
    e1.printStackTrace();
    } catch (IOException e2) {
    // TODO Auto-generated catch block
    e2.printStackTrace();
    } ObjectInputStream inData = new ObjectInputStream(clientSocket
    .getInputStream());
    ObjectOutputStream outData = new ObjectOutputStream(clientSocket
    .getOutputStream()); outData.writeObject("Verify");
    outData.writeObject("shimo"); String s = "";
    try {
    while (true) {
    s = inData.readObject().toString();
    System.out.println(s);
    s = "";
    }
    } catch (ClassNotFoundException e) {
    // TODO Auto-generated catch block
    System.out.println("receive from server ERROR!");
    e.printStackTrace();
    }
    } public static void main(String[] args) throws IOException {
    new LogGUI();
    }
    }服务器端
    import java.net.*;
    import java.sql.*;
    import java.util.Hashtable;
    import java.io.*;public class logRegServer implements Serializable {
    private static final long serialVersionUID = 1L;
    ServerSocket serverSocket;
    final int port = 1444; // 服务器和客户端监听的默认端口号 // 该Hashtable用于记录链接服务器的客户端信息
    private Hashtable<Socket, ObjectOutputStream> ht = new Hashtable<Socket, ObjectOutputStream>(); public static void main(String[] args) throws IOException {
    new logRegServer();
    } public logRegServer() throws IOException {
    Socket clientSocket; try {
    // 建立服务器套接字
    serverSocket = new ServerSocket(port); System.out.println("Log and Register Server started at: "
    + serverSocket.getInetAddress().getLocalHost() + ":" +
    // InetAddress.getLocalHost()+":"+
    serverSocket.getLocalPort()); while (true) {
    // 服务器监听客户端的链接
    clientSocket = serverSocket.accept();
    System.out.println("Connection from: " + clientSocket); // 建立客户端的输出数据流
    // DataOutputStream outData=new
    // DataOutputStream(clientSocket.getOutputStream());
    ObjectOutputStream outData = new ObjectOutputStream(
    clientSocket.getOutputStream());
    outData.writeObject("发送返回给客户端的object对象放这里"); // 将客户端套接字和客户端对应的输出数据流绑定并添加到Hashtable中记录
    ht.put(clientSocket, outData); // 新建立服务器线程,用于处理客户端的请求服务
    Thread thread = new Thread(new serverThread(clientSocket, ht));
    thread.start(); // 线程开始运行
    }
    } catch (IOException e) {
    e.printStackTrace(); }
    }
    }class serverThread extends Thread implements Runnable, Serializable {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private Socket clientSocket;
    private Hashtable ht; public serverThread(Socket clientSocket, Hashtable ht) {
    this.clientSocket = clientSocket;
    this.ht = ht;
    } public void run() {
    ObjectInputStream inData;
    String logName = ""; // 用户登录名 try {
    // 建立客户端输入/输出数据流
    inData = new ObjectInputStream(clientSocket.getInputStream()); while (true) {
    // 接受客户端发送来的请求消息 // 读取客户端发送来的消息标识
    String inStrType = inData.readObject().toString();
    System.out.println("消息类型:" + inStrType); // 依据请求消息的起始部分,判断客户端请求服务的内容 if (inStrType == "Verify") { // 密码验证
    logName = inData.readObject().toString();
    System.out.println("用户名:" + logName); /*
     * try{ Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); try {
     * Connection
     * c=DriverManager.getConnection("jdbc:odbc:onlineJudge");
     * Statement s=c.createStatement();
     * 
     * ObjectOutputStream outData=new
     * ObjectOutputStream(clientSocket.getOutputStream());
     * 
     * //返回对应用户名的密码 ResultSet rs=s.executeQuery("select password
     * from userInfoTable where userName='shimo'");
     * 
     *//** 如果用户存在 */
    /*
     * if(rs.next()){
     * outData.writeObject(rs.getString("password"));
     * outData.flush(); }else{
     * outData.writeObject("UserNotExist@"); outData.flush(); }
     * 
     * outData.close(); //关闭数据库链接 s.close(); c.close(); }catch
     * (SQLException se) { //未找到数据库,捕获异常 while (se != null) {
     * String SQLState = se.getSQLState(); String SQLMessage =
     * se.getMessage(); System.out.println("Error = "+SQLState);
     * System.out.println(SQLMessage); se =
     * se.getNextException(); } } }catch(ClassNotFoundException
     * e){ //未找到数据源驱动,捕获异常 e.printStackTrace(); }
     */
    }
    }
    } catch (IOException e) {
    // TODO Auto-generated catch block 
    e.printStackTrace();
    } catch (ClassNotFoundException e) {
    // TODO Auto-generated catch block 
    e.printStackTrace();
    } finally {
    System.out.println("end");
    }
    } //end run 
    }
      

  4.   

    谢谢jasonwhy,kokobox等各位网友,尤其是jasonwhy的测试。我的问题已经解决,但是我的方法却不同于jasonwhy,我的错误应该属于用同一个outPutStream构建了多个ObjectOutputStream导致序列化错误。因为在服务器端接收客户端链接时,我用Hashtable保存了clientSocket和他的ObjectOutputStream对象,并传入了客户端的执行线程中。但是我在线程中发送消息时又实例化了ObjectOutputStream。所以发送消息的时候会出现 [serialization stream header1] [object serialization form1] [serialization stream header2] [object serialization form2]...我把Hashtable换成了Vector只保存clientSocket就ok了。:-),虽然紧接着出现了其他的错误,但我觉得这个错误应该是这样的原因吧。关于序列化的,我参考了http://www.javaworld.com.tw/jute/post/view?bid=29&id=221962&sty=1;