socket:客户端接收不了服务器的消息

jovial__ 2008-04-20 03:14:58
我写的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();
}
}

谢谢大家!
...全文
740 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
jovial__ 2008-04-20
  • 打赏
  • 举报
回复
谢谢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;
jasonwhy 2008-04-20
  • 打赏
  • 举报
回复
程序有三个问题如下,帮你修改了一下:
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
}

linggan8 2008-04-20
  • 打赏
  • 举报
回复
把主要的问题写出来就好了!!
Inhibitory 2008-04-20
  • 打赏
  • 举报
回复
有可能是服务器端发送消息后并没有强制清空缓冲区, 以至于发送的消息必须等到缓冲区满后才能一次性发送, 试着每发送一次消息, 清空一次缓冲区试试.
kokobox 2008-04-20
  • 打赏
  • 举报
回复
可能是你读取操作的文件已经损坏造成的,或是文件对象没有可序列实例化,lz重新序列实例化一下对象。

lz可以看下我给别人解决的帖子:

http://topic.csdn.net/u/20080405/17/80c2af21-0fa4-431a-bc7a-fec60f028f76.html
kokobox 2008-04-20
  • 打赏
  • 举报
回复
好多的代码.........看着有点....
jovial__ 2008-04-20
  • 打赏
  • 举报
回复
帖子,找不到编辑。发的时候忘了标识了。

错误为:在客户端接收消息的那个语句上。

客户端代码: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)
kevinchj 2008-04-20
  • 打赏
  • 举报
回复
自己先调试一下看看,哪一块出的问题……

62,623

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧