我新学习了个聊天程序,用eclipse写的客户端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(400, 300);
add(tfTxt, BorderLayout.SOUTH);
add(taContent, BorderLayout.NORTH);
pack();
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
disconnect();
}
});
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 {
bConnected = false;
tRecv.join();

} catch (InterruptedException e) {
e.printStackTrace();
} finally {
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();
//taContent.setText(str);
tfTxt.setText("");

try {
//System.out.println(s);
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);
}

/* 
for(Inerator<Client> it = clients.iterator(); it.hasNext(); ) {
Client c = it.next();
c.send(str);
}
*/


} catch (SocketException e) {
System.out.println("退出了");//有错
} 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();
 }
}

}

}
}
注释有错的地方不知道怎么改了请帮忙.

解决方案 »

  1.   

    不打印System.out.println("退出了");//有错  这句就会报错,不得已打印了一下.谁教我一下怎么改?
      

  2.   

    用printStackTrace();
    打印一下错误的原因
      

  3.   

    这种程序,最好是在关键的地方,用System.out.println();打印一下,看看值在机上调试网络编程高度最麻烦了
      

  4.   

          } catch (SocketException e) {
            System.out.println("退出了");// 有错
          } catch (EOFException e) {
            System.out.println("Client closed");
          } catch (IOException e) {
            e.printStackTrace();
          } finally {
            clients.remove(this); // 在这里增加一句,将刚才推出的线程从你的线程列表里面移除就行了
    代码我收藏了,http://www.java2000.net/viewthread.jsp?tid=6587
      

  5.   


     } catch (SocketException e) {
            System.out.println("退出了");// 有错
          } catch (EOFException e) {
            System.out.println("Client closed");
          } catch (IOException e) {
            e.printStackTrace();
          } finally {
            clients.remove(this); // 在这里增加一句,将刚才推出的线程从你的线程列表里面移除就行了
    你这样能改好
    我真服了你
    不知道就不要乱说
      

  6.   

    这种程序异常很多主要是EOFException 和 SorketException 因为代码中有很多核心方法都属于阻塞式方法  例如readUTF(); 所以很可能你运行时没什么错  但一关闭客护端就报错 错误比较难处理 新手学习建议把异常全部抛出,把掌握核心思路就行了细研究的话,应该有相关书籍吧
      

  7.   


    java.net.SocketException: Connection reset
    at java.net.SocketInputStream.read(SocketInputStream.java:168)
    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 ChatServer$Client.run(ChatServer.java:104)
    at java.lang.Thread.run(Thread.java:595)
    -------------------
    while (bConnected)
    {

            //客户端死了,dis就完了.这里不能再读了.
            

    String str = dis.readUTF();
    System.out.println(str);
    for (int i = 0; i < clients.size(); i++)
    {
    Client c = clients.get(i);
    c.send(str);
    } /*
    * for(Inerator <Client> it = clients.iterator();
    * it.hasNext(); ) { Client c = it.next(); c.send(str); }
    */ }
      

  8.   

    在服务器端的send()中,删除断开的client
    public void send(String str) 
    {
       try {
    dos.writeUTF(str);
    } catch (IOException e) {
     clients.remove(this);
    //e.printStackTrace();
    }
    }