我做了一个聊天程序,大部分异常和BUG都处理完了,但目前还存在个bug不能解决~求各位高手帮帮我啊!!
    当一个客户端用非正常手段(强行关闭)终止后会服务器和其他客户端都会出现错误,我想问题是出在了非法关闭上,因为该客户端没有在服务器上被注销。但始终想不出什么好的办法解决~强人请帮忙啊!!
//------------------------------------------------------------------------//服务端代码:
/*
 *@author Vida ,CreatDate 2006-12-23
 *版本更新-与上一个把版本相同。
 */import java.io.IOException;
import java.net.*;
import java.io.*;
import java.util.*;public class CharServer
{
ServerSocket ss = null; boolean bStarted = false; ArrayList<Client> Clients = new ArrayList<Client>();
public static void main(String[] args)
{
new CharServer().start();
} void start()
{
try
{
ss = new ServerSocket(8888);
bStarted = true;
while (bStarted)
{
Socket s = ss.accept();
System.out.println("A client Connected!");
Client c = new Client(s);
Clients.add(c);
new Thread(c).start(); }
}
catch (BindException be)
{
System.out.println("The port in use!");
System.out.println("Please bind the other one.");
} catch (IOException e)
{
e.printStackTrace();
} } class Client implements Runnable
{
Socket s = null; InputStream is = null; OutputStream os = null; char[] ca = new char[1024]; InputStreamReader isr = null; BufferedReader br = null; OutputStreamWriter osw = null; BufferedWriter bw = null; String str = null; boolean bConnect = false; int count; public Client(Socket s)
{
this.s = s;
try
{
is = s.getInputStream();
os = s.getOutputStream();
}
catch (IOException e)
{
e.printStackTrace();
}
bConnect = true; } public void run()
{
isr = new InputStreamReader(is);
br = new BufferedReader(isr);
while (bConnect)
{
try
{
count = br.read(ca);
}
catch (IOException e)
{
e.printStackTrace();
}
try
{
String str = new String(ca, 0, count);
System.out.println(str);
for(int i=0; i<Clients.size(); i++)
{
Client c= Clients.get(i);
c.send(str);
}
/*Iterator<Client> it=Clients.iterator();
while(it.hasNext())
{
Client c=it.next();
c.send(str);
}*/ }
catch (StringIndexOutOfBoundsException sioobe)
{
System.out.println("The Client closed!");
bConnect = false;
try
{
br.close();
br=null;
}
catch (IOException e)
{
e.printStackTrace();
} try
{
s.close();
s=null;
}
catch (IOException e)
{
e.printStackTrace();
}
Clients.remove(this);

} } } void send(String str)
{ osw = new OutputStreamWriter(os);
bw = new BufferedWriter(osw);
try
{
bw.write(str);
}
catch (IOException e)
{
e.printStackTrace();
}
try
{
bw.flush();
}
catch (IOException e)
{
e.printStackTrace();
} }
}
}
//-----------------------------------------------
//客户端代码
import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
import java.net.*;
import java.io.*;/*
 *@author Vida ,CreatDate 2006-12-23
 *版本更新-解决了关闭客户端时输入流阻塞无法退出或报出异常的问题。
 */public class CharClinet extends Frame
{ private static final long serialVersionUID = 1L; private Panel panel = null; private TextArea taMessage = null; private TextField tfTalk = null; private Socket s = null; OutputStreamWriter osr = null; BufferedWriter bw = null;

InputStreamReader isr = null; BufferedReader br = null; Thread t = null; char[] ca = new char[1024 * 10]; final String stLine = System.getProperty("line.separator"); boolean bConnect = false;

Thread tRec; public CharClinet()
{
super();
initialize();
connect();
tRec=new Thread(new Receive());
tRec.start();
} private Panel getPanel()
{
if (panel == null)
{
panel = new Panel();
panel.setLayout(new BorderLayout());
panel.add(getTaMessage(), BorderLayout.NORTH);
panel.add(getTfTalk(), BorderLayout.SOUTH);
}
return panel;
} private TextArea getTaMessage()
{
if (taMessage == null)
{
taMessage = new TextArea("", 0, 0,
TextArea.SCROLLBARS_VERTICAL_ONLY);
taMessage.setEditable(false);
}
return taMessage;
} private TextField getTfTalk()
{
if (tfTalk == null)
{
tfTalk = new TextField();
tfTalk.addActionListener(new TextFieldListener());
} return tfTalk;
} private void initialize()
{
this.setLocation(200, 200);
this.setSize(400, 300);
this.setTitle("CharClient");
this.add(getPanel(), BorderLayout.CENTER); this.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
disconnect();
System.exit(0);
}
});
this.pack();
this.setVisible(true);
} private void connect()
{
try
{
s = new Socket("127.0.0.1", 8888);
System.out.println("Connected a server!");
bConnect = true;
osr = new OutputStreamWriter(s.getOutputStream());
bw = new BufferedWriter(osr);
}
catch (UnknownHostException e)
{
e.printStackTrace();
}
catch (ConnectException ce)
{
System.out.println("The Server has fault ,can't to connect!");
}
catch (IOException e)
{
e.printStackTrace();
} } private void disconnect()
{
if (bw != null || s != null)
{
bConnect = false;
try
{
bw.close();
bw=null;
br.close();
br=null;
s.close();
s=null;
}
catch (IOException e)
{
e.printStackTrace();
}

}
else
{
System.out.println("You never to connect!");
}
} public static void main(String[] args)
{
new CharClinet();
} private class TextFieldListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
String stTalk = tfTalk.getText().trim();
tfTalk.setText("");
/*
 * taMessage.append(stTalk); taMessage.append(stLine);
 */
if (bw != null)
{
try
{ bw.write(stTalk.toCharArray());
bw.flush(); }
catch (IOException e1)
{
e1.printStackTrace();
}
}
else
{
System.out.println("Connect Error! The message counld not send !");
}
}
} private class Receive implements Runnable
{
Receive()
{
try
{
isr = new InputStreamReader(s.getInputStream());
}
catch (IOException e)
{
e.printStackTrace();
}
br = new BufferedReader(isr);
} public void run()
{
while (bConnect)
{
receiveMessage();
} } private void receiveMessage()
{
try
{
int i = br.read(ca);
taMessage.append(new String(ca, 0, i));
taMessage.append(stLine); }
catch(SocketException e)
{
System.out.println("Client Exit!");
}
catch (IOException e)
{
e.printStackTrace();
} }
}}

解决方案 »

  1.   

    代码太长了,没看你说得问题其实很好解决。客户端强制关闭是无法避免的,当客户端关闭后,服务端的io操作必然会出错,你需要的是一个try...catch...动作。捕捉到网络错误后就认为这个用户已经退线,or掉线,然后做相应的销毁动作就可以了
      

  2.   

    fool_leave(请及时结贴) 
    你怎么去判断是哪个客户端出错啊?
      

  3.   

    你不是把client放到一个ArrayList里面了吗在对client io操作的时候报错的就是这个client呀,从ArrayList里面remove出来处理不过一般这样的网络应用都是通过HashMap来存储用户的,key就是用户的名字(在用户登录的时候就知道了)。这样方便操作反正就是谁的网络操作出错就把谁kick了,不能影响其它用户
      

  4.   

    欢迎加入QQ群:32943114
    面向组件的软件开发, 专注net, java技术.
    探讨新一代软件特征webOS, 第三代搜索引擎技术,P2P,Grid,动态语言, AJAX, 虚拟操作系统
      

  5.   

    我试过了~~那个出错的客户端是remove掉了~但remove了后其他客户端进入了一个死循环!