我写的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();
}
}谢谢大家!
我简化后的程序如下: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();
}
}谢谢大家!
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)
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
}