问题:
服务器端退出,线程却还在运行
报错:
java.net.SocketException: Socket closed
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:152)
at java.net.SocketInputStream.read(SocketInputStream.java:122)
at java.net.SocketInputStream.read(SocketInputStream.java:210)
at java.io.DataInputStream.readUnsignedShort(DataInputStream.java:337)
at java.io.DataInputStream.readUTF(DataInputStream.java:589)
at java.io.DataInputStream.readUTF(DataInputStream.java:564)
at talkingRoom.Servicer$1.run(Servicer.java:127)
*********客户端************************
import java.awt.*;
import java.net.*;
import java.awt.event.*;
import java.io.*;
import javax.swing.*;
@SuppressWarnings("serial")
public class Desktop extends JFrame implements ActionListener {
@SuppressWarnings("unused")
private class WindowCloser extends WindowAdapter {
public void windowClosing(WindowEvent we) {
System.exit(0);
}
}
private Socket cs = null;
private JPanel p = new JPanel();
private JTextArea output = new JTextArea();
private JTextField input = new JTextField();
private DataOutputStream dos;
private DataInputStream dis;
private JButton b1 = new JButton("进入");
private JButton b2 = new JButton("退出");
private JLabel fuwuqis = new JLabel("服务器:");
private JTextField fuwuqi = new JTextField("127.0.0.1");
private JLabel duankous = new JLabel("端口:");
private JTextField duankou = new JTextField("8888");
private JLabel nichengs = new JLabel("昵称:");
private JTextField nicheng = new JTextField("游客1");
private JButton b3 = new JButton("发送");
private String talking;
private boolean started = false;
private boolean bConnected = false;
//UI界面(不需要再修改)
Desktop() {
p.setLayout(new BorderLayout());
JPanel p1 = new JPanel();
JPanel p2 = new JPanel();
p1.add(b1);
b1.addActionListener(this);
p1.add(b2);
b2.addActionListener(this);
p1.add(fuwuqis);
p1.add(fuwuqi);
p1.add(duankous);
p1.add(duankou);
p1.add(nichengs);
p1.add(nicheng);
p2.setLayout(new BorderLayout());
p2.add(input, BorderLayout.CENTER);
p2.add(b3, BorderLayout.EAST);
b3.addActionListener(this);
p.add(p1, BorderLayout.NORTH);
p.add(p2, BorderLayout.SOUTH);
p.add(output, BorderLayout.CENTER);
buttonclose();
this.setTitle("聊天室for客户端");
this.add(p);
this.setSize(500, 300);
this.setVisible(true);
}
public void buttonclose() {
b1.setEnabled(true);
b2.setEnabled(false);
b3.setEnabled(false);
input.setEditable(false);
fuwuqi.setEditable(true);
duankou.setEditable(true);
nicheng.setEditable(true);
}
public void buttonopen() {
b1.setEnabled(false);
b2.setEnabled(true);
b3.setEnabled(true);
input.setEditable(true);
fuwuqi.setEditable(false);
duankou.setEditable(false);
nicheng.setEditable(false);
}
//连接函数,流与Socket所在
public void connect() {
try {
cs = new Socket(fuwuqi.getText(), Integer.parseInt(duankou.getText()));
System.out.print("加入连接");
dos = new DataOutputStream(cs.getOutputStream());
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
//断开函数,流与Socket所在
public void disconnect() {
try {
bConnected = false;
dos.writeUTF("$%$");
dis.close();
dos.close();
System.out.println("disdos.close");
cs.close();
System.out.println("cs.close");
output.append("退出成功\n");
buttonclose();
} catch (IOException e) {
e.printStackTrace();
}
}
//发送流函数
public void send() {
try {
if(talking == null) {
dos.writeUTF("");
}else {
dos.writeUTF(talking);
}
dos.flush();
} catch (IOException e1) {
e1.printStackTrace();
}
}
//接收流函数
public void receive() {
try {
started = true;
bConnected = true;
dis = new DataInputStream(cs.getInputStream());
new Thread() {
public void run() {
System.out.println("开始接收");
while (bConnected) {
String talking = "";
try {
talking = dis.readUTF();
output.append("\n\r" + "主机" + " : " + talking);
if("$%$".equalsIgnoreCase(talking)){
disconnect();
}
} catch (IOException e) {
e.printStackTrace();
}
}
// try {
// dis.close();
// } catch (IOException e) {
// e.printStackTrace();
// }
}
}.start();
} catch (IOException e1) {
e1.printStackTrace();
}
}
public void actionPerformed(ActionEvent e) {
String S = e.getActionCommand();
if ("发送".equalsIgnoreCase(S)) {
talking = input.getText().trim();
String snicheng = nicheng.getText().trim();
output.append("\n\r" + snicheng + " : " + talking);
input.setText("");
try {
dos.writeUTF(snicheng);
} catch (IOException e1) {
e1.printStackTrace();
}
send();
} else if ("进入".equalsIgnoreCase(S)) {
connect();
receive();
output.append("进入成功\n 服务器:" + fuwuqi.getText() + "\t端口:" + duankou.getText() + "\t昵称:" + nicheng.getText() + "\n");
buttonopen();
} else if ("退出".equalsIgnoreCase(S)) {
disconnect();
}
}
public static void main(String args[]) {
new Desktop();
}
}
***********服务器********************************
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import javax.swing.*;
@SuppressWarnings("serial")
public class Servicer extends JFrame implements ActionListener {
@SuppressWarnings("unused")
private class WindowCloser extends WindowAdapter {
public void windowClosing(WindowEvent we) {
System.exit(0);
}
}
private ServerSocket ss = null;
private Socket s;
private JPanel p = new JPanel();
private JTextArea output = new JTextArea();
private JTextField input = new JTextField();
private DataOutputStream dos;
private DataInputStream dis;
private JButton b1 = new JButton("启动");
private JButton b2 = new JButton("退出");
private JButton b3 = new JButton("发送");
private String talking, nicheng;
private boolean started = true;
private boolean bConnected = false;
// UI界面(不需要再修改)
Servicer() {
p.setLayout(new BorderLayout());
JPanel p1 = new JPanel();
JPanel p2 = new JPanel();
p1.add(b1);
b1.addActionListener(this);
p1.add(b2);
b2.addActionListener(this);
b3.addActionListener(this);
p2.setLayout(new BorderLayout());
p2.add(input, BorderLayout.CENTER);
p2.add(b3, BorderLayout.EAST);
p.add(p1, BorderLayout.NORTH);
p.add(p2, BorderLayout.SOUTH);
p.add(output, BorderLayout.CENTER);
b2.setEnabled(false);
b1.setEnabled(true);
b3.setEnabled(false);
input.setEditable(false);
output.setEditable(false);
this.setTitle("聊天室for服务端");
this.add(p);
this.setSize(500, 300);
this.setVisible(true);
}
public void buttonclose() {
b1.setEnabled(true);
b2.setEnabled(false);
b3.setEnabled(false);
input.setEditable(false);
}
public void buttonopen() {
b1.setEnabled(false);
b2.setEnabled(true);
b3.setEnabled(true);
input.setEditable(true);
}
public void disconnect() {
started = false;
bConnected = false;
try {
dos.writeUTF("$%$");
dos.close();
dis.close();
s.close();
System.out.println("Servicer dos.close");
ss.close();
System.out.println("Servicer cs.close");
} catch (IOException e) {
e.printStackTrace();
}
}
public void start() {
try {
ss = new ServerSocket(8888);
} catch (IOException e) {
e.printStackTrace();
}
try {
started = true;
//while(started){
s = ss.accept();
output.append("新加入,已连接");
buttonopen();
bConnected = true;
dos = new DataOutputStream(s.getOutputStream());
dis = new DataInputStream(s.getInputStream());
link();
//}
} catch (IOException e1) {
e1.printStackTrace();
}
}
public void send() {
talking = input.getText().trim();
try {
if(talking == null) {
dos.writeUTF("");
} else {
dos.writeUTF(talking);
}
dos.flush();
} catch (IOException e1) {
e1.printStackTrace();
}
}
public void link() {
new Thread(){
public void run() {
String nicheng = null;
try {
nicheng = dis.readUTF();
} catch (IOException e1) {
output.append("\n\r用户名获取异常");
e1.printStackTrace();
}
while (bConnected) {
String talking = "";
try {
talking = dis.readUTF();
} catch (IOException e) {
e.printStackTrace();
}
if("$%$".equalsIgnoreCase(talking)){
disconnect();
}
output.append("\n\r" + nicheng + " : " + talking);
}
// try {
// dis.close();
// } catch (IOException e) {
// e.printStackTrace();
// }
}
}.start();
}
public void actionPerformed(ActionEvent e) {
String S = e.getActionCommand();
String takeing = input.getText().toString();
if ("启动".equalsIgnoreCase(S)) {
start();
} else if ("退出".equalsIgnoreCase(S)) {
disconnect();
output.append("退出成功");
} else if ("发送".equalsIgnoreCase(S)) {
send();
output.append("\n\r" + "主机" + " : " + takeing);
input.setText("");
}
}
public static void main(String args[]) {
new Servicer();
}
}
服务器端代码修改一下
private volatile boolean bConnected = false;//增加volatile
public void disconnect() {
started = false;
bConnected = false;
try {
dos.writeUTF("$%$");
dos.close();
dis.close();
s.close();
System.out.println("Servicer dos.close");
ss.close();
System.out.println("Servicer cs.close");
buttonclose();//增加这句话,修改按钮状态
} catch (IOException e) {
e.printStackTrace();
}
}
Action.java(获得消息的Action)代码:/** * 进行聊天 */public String chat(int type, String text, String userId, String otherUserId, String matchId) { switch(type) { case 1: ......
答案就在这里:Java聊天室
----------------------Hi,地球人,我是问答机器人小S,上面的内容就是我狂拽酷炫叼炸天的答案,除了赞同,你还有别的选择吗?