客户端程序
package UI;import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Hashtable;import MODEL.BookInfor;
import MODEL.State;
public class Client extends Frame implements Runnable, ActionListener,
ItemListener {
private Socket socket = null;
private ObjectInputStream inputStream = null;
private ObjectOutputStream outputStream = null;
private Thread initThread, threadGetData;
private TextArea textArea;
private Choice choice;
private TextField bookNameTextField;
private Button qureyButton;
private Hashtable<String, String> map = new Hashtable<String, String>(); public Client(String s) throws IOException {
super(s);
// 默认为边界布局
setBounds(100, 100, 600, 500);
try {
socket = new Socket("127.0.0.1", 2528);
} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
Panel upPanel = new Panel();
bookNameTextField = new TextField(18);
choice = new Choice();
qureyButton = new Button("查询");
qureyButton.addActionListener(this);
choice.add("--请选择书的类型--");
upPanel.add(new Label("请输入书名:"));
upPanel.add(bookNameTextField);
upPanel.add(new Label("请选择书的类型:"));
upPanel.add(choice);
upPanel.add(qureyButton);
// 初始化数据返回区
textArea = new TextArea();
textArea.setText("\n\n\n\n\t\t欢迎使用!!!!!\n\n\t\t\tme");
textArea.setEditable(false);
// 数据传输通道初始化
inputStream = new ObjectInputStream(socket.getInputStream());
outputStream = new ObjectOutputStream(socket.getOutputStream());
// 初始化线程
initThread = new Thread(this);
initThread.start();
threadGetData = new Thread(this);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
add(upPanel, BorderLayout.NORTH);
add(textArea, BorderLayout.CENTER);
validate();
setVisible(true);
} public static void main(String[] args) {
try {
new Client("简易图书查询");
} catch (IOException e) {
System.out.println("服务器断开");
}
} public void run() {
// 以前读的数据没有进行清理
ArrayList<BookInfor> bookInforArrayList = null;
ArrayList<State> stateArrayList = null;
if (Thread.currentThread() == threadGetData) {
try {
bookInforArrayList = (ArrayList<BookInfor>) inputStream
.readObject();
} catch (IOException e) {
System.out.println("服务器断开");
return;
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
if (bookInforArrayList.size() == 0) {
textArea.setText("\n\n\n\n\t\t\t没有该图书");
System.out.println("空的返回值线程死亡");
return;
}
textArea.setText("");
textArea
.append("书名\t\t\t书的编号\t\t\t书的类型\t\t\t状态\t\t\t出版社\t\t\t作者\t\t\t数量\t\t\t入库日期\t\t\t\n");
for (BookInfor bookInfor : bookInforArrayList) {
textArea.append(bookInfor.getBookName() + "\t\t\t"
+ bookInfor.getBookNumber() + "\t\t\t\t"
+ bookInfor.getBookType() + "\t\t\t"
+ bookInfor.getBookState() + "\t\t\t"
+ bookInfor.getBookPublic() + "\t\t\t"
+ bookInfor.getBookAuthor() + "\t\t\t"
+ bookInfor.getBookCount() + "\t\t\t"
+ bookInfor.getBookInputDate() + "\t\t\t\n");
} }
if (Thread.currentThread() == initThread) {
try {
try {
stateArrayList = (ArrayList<State>) inputStream
.readObject();
if (stateArrayList.size() == 0) {
textArea.setText("书的类型为空,请添加");
return;
}
for (State state : stateArrayList) {
choice.add(state.getTypeName());
}
choice.addItemListener(this);
// 初始化完毕销毁线程
return;
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
} catch (IOException e) {
System.out.println("服务器断开");
return;
}
}
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == qureyButton) {
try {
if (!bookNameTextField.getText().equals("")) {
map.put("BookName", bookNameTextField.getText());
}
outputStream.writeObject(map);
outputStream.flush();
// 清空传送容器
map.clear();
if (!(threadGetData.isAlive())) {
threadGetData = new Thread(this);
}
if (threadGetData.getState() == Thread.State.NEW) {
threadGetData.start();
}
} catch (IOException e1) {
System.out.println("客户端向服务器发送异常行号121");
e1.printStackTrace();
}
}
} public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
Choice choice = (Choice) e.getSource();
int select = choice.getSelectedIndex();
if (select != 0) {
map.put("BookTypeID", Integer.toString(select));
}
}
}
}
服务端程序:
package UI;import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Hashtable;import DAL.DataFactory;
import MODEL.BookInfor;public class ServerThread extends Thread {
Socket socket = null;
ObjectOutputStream outputStream;
ObjectInputStream inputStream;
ArrayList<BookInfor> bookInforarrayList;
Hashtable<String, String> maps;
public ServerThread(Socket socket) throws SQLException, IOException {
this.socket = socket;
// 对客户端初始化的数据
ArrayList<MODEL.State> stateArrayList = null;
try {
outputStream = new ObjectOutputStream(this.socket.getOutputStream());
inputStream = new ObjectInputStream(this.socket.getInputStream());

stateArrayList = DataFactory.executeQueryState();
} catch (IOException e) {
System.out.println("服务器输出异常");
} finally {
outputStream.writeObject(stateArrayList);
outputStream.flush();
}
// 启动线程
this.start();
} public void run() {
while (true) {
try {
// 获取请求
maps = (Hashtable<String, String>) (inputStream.readObject());
System.out.println("正确读取的map1:" + maps);
bookInforarrayList = DataFactory.executeQueryBookInfor(maps);
maps.clear();
// 返回
outputStream.writeObject(bookInforarrayList);
outputStream.flush();
} catch (IOException e) {
System.out.println("客户离开");
return;
} catch (ClassNotFoundException e) {
return;
}
}
}}只能接收到第一次传输的数据。以后不管客户端向其发送什么数据,收到的结果都是第一次的数据。比如:在客户端第一次发送一个:"你好". 服务器端能接收到并成功反序列化并再序列化后回发给客户端。当客户端再向服务器端发送一个:"wo“服务端接收到的还是”你好“

解决方案 »

  1.   

    你的代码格式有点乱。[[code=Java]用这样的。/code]   
      

  2.   

    客户端按钮事件的这个地方修改一下,把outputStream发送前重新reset
    if (!bookNameTextField.getText().equals("")) {
    map.put("BookName", bookNameTextField.getText());
    }
    outputStream.reset(); //在这里追加一个reset
    outputStream.writeObject(map);
    //强制发送
    outputStream.flush();原因大概说明一下,在socket传送时,为了防止一个对象被引用多次而发送多次,内部作了个标识以识别重复,如果重复,则还是发送原来的,除非reset一下,把标识清空,或者重新new一个对象,然后引用新的对象,也就是说在你发送完map后重新map=new HashMap<String, String>也能达到同样的效果,再次发送map时会发现不是原来的对象了,不会检查标识。这里要注意,修改对象的属性不会改变该标识,因为即使属性变了,对象还是存在于原来的那块内存地址,所以传输时发现引用的是重复的内存地址,所以还是发送原来旧的。