java.net.SocketException: socket closed异常,我很困惑。。

guoshuai213 2010-02-12 02:16:47
以下是我的客户端程序代码:

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();

public static void main(String[] args) {
new ChatClient().lauchFrame();
}

public void lauchFrame() {
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 e) {
disconnect();
System.exit(0);

}

});
tfTxt.addActionListener(new TFListener());

setVisible(true);
connect();
new Thread(new RecvThread()).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();
s.close();
}catch(IOException e){
e.printStackTrace();
}
}


private class TFListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
String str = tfTxt.getText().trim();
taContent.setText(str);
tfTxt.setText("");

try {
System.out.println(s);
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
dos.writeUTF(str);
dos.flush();
dos.close();
} catch (IOException e1) {

e1.printStackTrace();
}

}

}

private class RecvThread implements Runnable{

public void run() {
try{
while(bConnected){

String str = dis.readUTF();

// System.out.println(str);
// taContent.setText(taContent.getText()+str+"\n");
}
} catch(IOException e){
e.printStackTrace();
}
}
}

}
/////////////////////////////////
服务器端程序代码:
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);
//dis.close();
}

}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();
}

}
}

}
}

///////////////////////////////////////////////////////


麻烦有哪位好心的高手可以帮我看看,怎么解决这个问题啊,不然我真是苦恼极了。。当我把服务器端起来以后,先后启动了两个客户端,可是在在其中一个客户端发送了一条信息后(nihao),另一个客户端没有显示收到,却在客户端抛出了java.net.SocketException: socket closed这个异常,这是什么怎么一回事啊??


控制台信息:
客户端1:connected!
Socket[addr=/127.0.0.1,port=8888,localport=4434]
java.net.SocketException: socket closed
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at java.net.SocketInputStream.read(SocketInputStream.java:182)
at java.io.DataInputStream.readUnsignedShort(DataInputStream.java:307)
at java.io.DataInputStream.readUTF(DataInputStream.java:545)
at java.io.DataInputStream.readUTF(DataInputStream.java:522)
at ChatClient$RecvThread.run(ChatClient.java:99)
at java.lang.Thread.run(Thread.java:595)
///////////
客户端2:connected!

////////////////
服务器端:a client connected!
a client connected!
nihao
Client closed!


///////////////////////
正确的显示应该是两个客户端都显示收到
connected!
nihao
...全文
28315 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
xuanwuyanpopo 2012-06-01
  • 打赏
  • 举报
回复
今天学习马士兵的视频,写到聊天程序的时候也遇到类似的问题,搞了半天终于搞清楚了!
在网上搜索信息的时候搜到你两年前的帖子,本着多学习的精神仔细看了你的类容也发现了问题。
虽然你应该不会看了,但还是写一下吧。
你的ChatClient中的TextField的监听器相应类容有问题:
private class TFListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
String str = tfTxt.getText().trim();
taContent.setText(str);
tfTxt.setText("");

try {
System.out.println(s);
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
dos.writeUTF(str);
dos.flush();
dos.close(); //这里有问题,敲回车触发TextField的监听器时把dos关了,当然出错!
} catch (IOException e1) {

e1.printStackTrace();
}

}

}

这个是你问的主要的,另外还有一些其它的问题。
1)在RecvThread中收到了服务器发送过来的每个client发送的String时,你没有让他们显示在TextArea中
private class RecvThread implements Runnable{

public void run() {
try{
while(bConnected){

String str = dis.readUTF();

// System.out.println(str);
// taContent.setText(taContent.getText()+str+"\n"); //你把这句注释掉了,在其它client中当然没有
}
} catch(IOException e){
e.printStackTrace();
}
}
}

}

2)很多Exceptions没有处理,全是写的e.printStackTrace();
client关闭的时候应该提示,send方法调用之前判断一下对应Client的Socket是否已经关闭,若是从clients中remove();
guoshuai213 2010-02-13
  • 打赏
  • 举报
回复
可是,不知道这个异常是怎么引起的啊,麻烦你知道的话可以说的再清楚一点吗。。?
soli11722984 2010-02-12
  • 打赏
  • 举报
回复
要服务器一直跑着。。。。。。
就是LS的

while(true)
.....
meadking 2010-02-12
  • 打赏
  • 举报
回复
while(true)
.....

81,092

社区成员

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

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