黑马程序员技术交流社区
标题:
聊天系统客户端和服务端中Socket和阻塞式方法的问题
[打印本页]
作者:
刘学明
时间:
2013-4-21 00:02
标题:
聊天系统客户端和服务端中Socket和阻塞式方法的问题
本帖最后由 刘学明 于 2013-4-21 00:19 编辑
一个客户端程序 一个服务端程序
基本功能实现了 当开启多个客户端窗口进行聊天 先关闭其中的一个客户端 用其他客户端进行发送消息时
会报出 Socket close 的错误 请问如何完善程序才可以
服务端程序代码:
import java.io.*;
import java.net.*;
import java.util.*;
public class ChatServer {
boolean started = false;
ServerSocket ss = null;
List<Client> clients = new ArrayList<Client>();
public static void main(String[] args) {
new ChatServer().start();
}
public void start() {
try {
ss = new ServerSocket(8888);
started = true;
} catch (BindException e) {
System.out.println("端口使用中....");
System.out.println("请关掉相关程序并重新运行服务器!");
System.exit(0);
} catch (IOException e) {
e.printStackTrace();
}
try {
while(started) {
Socket s = ss.accept();
Client c = new Client(s);
System.out.println("a client connected!");
new Thread(c).start();
clients.add(c);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
class Client implements Runnable {
private Socket s;
private DataInputStream dis = null;
private DataOutputStream dos = null;
private boolean bConnected = false;
public Client(Socket s) {
this.s = s;
try {
dis = new DataInputStream(s.getInputStream());
dos = new DataOutputStream(s.getOutputStream());
bConnected = true;
} catch (IOException e) {
e.printStackTrace();
}
}
public void send(String str) {
try {
dos.writeUTF(str);
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
try {
while(bConnected) {
String str = dis.readUTF();
System.out.println(str);
for(int i=0; i<clients.size(); i++) {
Client c = clients.get(i);
c.send(str);
}
}
} catch (EOFException e) {
System.out.println("Client closed!");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(dis != null) dis.close();
if(dos != null) dos.close();
if(s != null) {
s.close();
}
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
}
复制代码
客户端程序代码:
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
public class ChatClient extends Frame {
Socket s = null;
DataOutputStream dos = null;
DataInputStream dis = null;
private boolean bConnected = false;
TextField tfTxt = new TextField();
TextArea taContent = new TextArea();
Thread tRecv = new Thread(new RecvThread());
public static void main(String[] args) {
new ChatClient().launchFrame();
}
public void launchFrame() {
setLocation(400, 300);
this.setSize(300, 300);
add(tfTxt, BorderLayout.SOUTH);
add(taContent, BorderLayout.NORTH);
pack();
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent arg0) {
disconnect();
System.exit(0);
}
});
tfTxt.addActionListener(new TFListener());
setVisible(true);
connect();
tRecv.start();
}
public void connect() {
try {
s = new Socket("127.0.0.1", 8888);
dos = new DataOutputStream(s.getOutputStream());
dis = new DataInputStream(s.getInputStream());
System.out.println("connected!");
bConnected = true;
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void disconnect() {
try {
dos.close();
dis.close();
s.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private class TFListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
String str = tfTxt.getText().trim();
tfTxt.setText("");
try {
dos.writeUTF(str);
dos.flush();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
private class RecvThread implements Runnable {
public void run() {
try {
while(bConnected) {
String str = dis.readUTF();
taContent.setText(taContent.getText() + str + '\n');
}
} catch (SocketException e) {
System.out.println("退出了,bye!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
复制代码
一个客户端 一个服务端 开启多个客户端进行聊天 关闭了其中一个客户端 其它的没关闭的客户端只要一发送消息 就会报出Socket Close的异常错误 是阻塞式方法WriteUTF()和ReadUTF()的原因吗 怎么修改程序
1.jpg
(50.74 KB, 下载次数: 28)
下载附件
2013-4-21 00:04 上传
作者:
袁梦希
时间:
2013-4-24 23:30
好长啊 如果说这段代码肯定是 网络流已经关闭了,好好跟老毕的视频对照一下看看哪里出问题了。
作者:
孙胜
时间:
2013-4-27 23:03
本帖最后由 孙胜 于 2013-4-27 23:05 编辑
你的问题在于关闭客户端是,并没有把这个客户端从集合中删除,这样就造成了向一个不存在的客户端发送消息,所以会报异常
我把你的代码修改了下,运行结果就没问题了
import java.io.*;
import java.net.*;
import java.util.*;
public class ChatServer {
boolean started = false;
ServerSocket ss = null;
Client client;<font color="#ff0000" size="5">//这里增加一个变量声明,run方法关闭资源前把客户端从集合中删除</font>
List<Client> clients = new ArrayList<Client>();
public static void main(String[] args) {
new ChatServer().start();
}
public void start() {
try {
ss = new ServerSocket(8888);
started = true;
} catch (BindException e) {
System.out.println("端口使用中....");
System.out.println("请关掉相关程序并重新运行服务器!");
System.exit(0);
} catch (IOException e) {
e.printStackTrace();
}
try {
while(started) {<font size="5" color="#ff0000">//把你原来的c换成client</font>
Socket s = ss.accept();
client = new Client(s);
System.out.println("a client connected!");
new Thread(client).start();
clients.add(client);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
class Client implements Runnable {
private Socket s;
private DataInputStream dis = null;
private DataOutputStream dos = null;
private boolean bConnected = false;
public Client(Socket s) {
this.s = s;
try {
dis = new DataInputStream(s.getInputStream());
dos = new DataOutputStream(s.getOutputStream());
bConnected = true;
} catch (IOException e) {
e.printStackTrace();
}
}
public void send(String str) {
try {
dos.writeUTF(str);
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
try {
while(bConnected) {
String str = dis.readUTF();
System.out.println(str);
for(int i=0; i<clients.size(); i++) {
Client c = clients.get(i);
c.send(str);
}
}
} catch (EOFException e) {
System.out.println("Client closed!");
} catch (IOException e) {
e.printStackTrace();
} finally {
clients.remove(client);<font color="#ff0000" size="5">//这里增加一行</font>
try {
if(dis != null) dis.close();
if(dos != null) dos.close();
if(s != null) {
s.close();
}
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
}
复制代码
作者:
黄玉昆
时间:
2013-4-28 23:17
如果仍有问题,请继续追问,如果问题已解决,请将分类改为已解决,谢谢
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2