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) {
// TODO Auto-generated catch block
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) {
clients.remove(this);
System.out.println("对方退出了!我从List里面去掉了!");
//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();
//s = null;
}

} catch (IOException e1) {
e1.printStackTrace();
}


}
}

}
}

解决方案 »

  1.   

    当一个方法中的代码过长的时候
    把有独立功能的部分重新封装成一个方法
    便于重用这个send这样一封装
    你在别的地方也可以用的上了
      

  2.   

    而且,既然这个send是个public方法
    就说明设计者是希望这个方法可以被直接通过对象调用如果把这个功能写死在run里面,
    那这个send的功能就不能通过对象来调用了
      

  3.   

    而且,既然这个send是个public方法
    就说明设计者是希望这个方法可以被直接通过对象调用如果把这个功能写死在run里面,
    那这个send的功能就不能通过对象来调用了
    -------------------------首先,谢谢。这个可以这样理解。
    Client c = clients.get(i);这个东西已经过去连接的个个客户端。
    那么使用send方法,是否跟
             private Socket s;
            private DataOutputStream dos 有关系呢。
    往指点。
      

  4.   

    我觉得写send()和直接写在run里面应该都可以把
      

  5.   

    和dos肯定是有关系的,send方法中用到了dos这个引用其实楼主你可以这样理解
    按你说的不写send方法,直接写在run的那一段,
    针对这个例子来说,完全可以没有问题但是,这样做的话
    1、破坏了设计者的原意
    2、代码重用度差
    仅此而已,针对这个例子来说,影响不大
      

  6.   

    再次感谢。sunyiz ,taoyongming