package TestSocket01; import java.awt.Color; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JScrollPane; import javax.swing.JTextArea; public class MyForm extends JFrame{ private static final long serialVersionUID = 1L; // private JButton jbSent = new JButton("发送"); private JLabel jlabelName = new JLabel("用户昵称:"); private JTextArea jtaName = new JTextArea(""); private JTextArea jtaShow = new JTextArea(""); private JTextArea jtaWrite = new JTextArea(""); public MyForm() { //测试! } public MyForm(String str) { super(str); } public void mShow() { this.setVisible(true); } public void mClose() { this.setDefaultCloseOperation(EXIT_ON_CLOSE); } public void mform() { this.setLayout(null); this.setBounds(300, 300, 500, 500); //this.getContentPane().setBackground(new Color(200, 90, 30)); nothing this.getContentPane().setBackground(Color.gray); jlabelName.setBounds(10, 10, 900, 25); jtaName.setBounds(100, 10, 200, 25); // jbSent.setBounds(400, 400, 80, 30); JScrollPane jspShow = new JScrollPane(jtaShow); JScrollPane jspWrite = new JScrollPane(jtaWrite); jspShow.setBounds(30, 40, 350, 350); jtaShow.setLineWrap(true); jtaShow.setEditable(false); jtaShow.setCaretPosition(jtaShow.getDocument().getLength()); jspWrite.setBounds(30, 400, 330, 35); jtaWrite.setLineWrap(true); jtaWrite.setCaretPosition(jtaWrite.getDocument().getLength()); this.add(jlabelName); this.add(jtaName); this.add(jspShow); this.add(jspWrite); } public String getName() { return jtaName.getText(); } public void setMessage(String message) { jtaShow.append(message+"/n"); //添加信息并换行。 //jtaShow.setWrapStyleWord(true); } public String getMessage() { if (!(jtaWrite.getText()).equals("")) { //如果写的东西不为空 if (!(jtaName.getText()).equals("")) { //判断是谁写的信息 return (jtaName.getText() + ": " + jtaWrite.getText()); } else { return ("ClientX: " + jtaWrite.getText()); //无名氏默认是ClientX } } else { //什么都没写 return ""; } } public void clearWrite() { //清空所写的东西。 jtaWrite.setText(""); } public static void main(String[] args) { MyForm mf = new MyForm(); //测试用的而已。 mf.mform(); mf.mShow(); mf.mClose(); } } package TestSocket01; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.Socket; import java.net.UnknownHostException; import javax.swing.JButton; public class socketClient implements Runnable { private Socket s; private DataInputStream dis; private DataOutputStream dos; private boolean flag = true; //标志 如果多个客户端则会出错。 private MyForm mf = new MyForm("通讯客户端"); //新建了一个客户端的界面。 private JButton jbSent = null; private boolean serverClose = false;// 标识服务器端是否关闭,true为关闭,false为没关闭 public socketClient() { mf.mform(); mf.mShow(); mf.mClose(); try { jbSent = new JButton("发送"); jbSent.setBounds(400, 400, 80, 30); //设置按钮的大小 mf.add(jbSent); //添加到JFrame中 s = new Socket("222.17.110.117", 55551); //此处新建了一个Socket,并连接服务器。通信从此位置开始。 jbSent.addActionListener(new ActionListener() { //“发送”按钮监听 public void actionPerformed(ActionEvent e) { //监听按钮的方法。必须实现的。 try { if(!serverClose){ // 第一次执行时,默认是开着的。之后,如果服务器开着,即没有关闭,则发送下面内容 String message = mf.getMessage(); //取得某人写的某些内容 if (!message.equals("")) { System.out.println(message); //后台打印测试而已! dos = new DataOutputStream(s.getOutputStream()); dos.writeUTF(message); //把message通过s输出去 mf.clearWrite(); //此处只有发送按钮在监听,故发送之后,内容理应删掉。 } } } catch (IOException ioe) { ioe.printStackTrace(); } } }); mf.addWindowListener(new WindowAdapter() { // 监听客户端是否关闭,如果关闭,则向服务器发送一个“exit”字符串 public void windowClosing(WindowEvent e) { try { if (serverClose) { //serverClose 的值一直都是false。 //此处永远不会被执行。 } else { //因为监听到了窗口被关闭了。 dos = new DataOutputStream(s.getOutputStream()); dos.writeUTF("exit"); //既然关闭了,就发送个信号给服务器。删除该客户端。 } } catch (IOException e1) { e1.printStackTrace(); } } }); new Thread(this).start(); //打开一个线程,即执行本类的run()函数。 } catch (UnknownHostException e) { e.printStackTrace();//打印出错信息而已,别无他意。 } catch (IOException e) { serverClose=true; mf.setMessage("服务器不存在或未打开!"); } } public void run() { while (flag) { try { dis = new DataInputStream(s.getInputStream()); mf.setMessage(dis.readUTF()); } catch (IOException e) { serverClose = true; //服务器可能在有客户端存在的时候关闭,此时,客户端输入流会出错,刚执行此处 mf.setMessage("服务器关闭了!"); flag=false;//跳出循环 } } } public static void main(String[] agrs) { new socketClient(); //先开服务器,再开客户端。代码入口处。 } } package TestSocket01; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.Vector; //服务器端 public class socketServer { private ServerSocket ss; private Socket s; private DataInputStream dis; private DataOutputStream dos; private static Vector<Client> v = new Vector<Client>(); private Client client; public socketServer() { try { ss = new ServerSocket(55551); System.out.println("服务器已经启动!"); //后台提示 while (true) { try { s = ss.accept(); //一直在等待连接 System.out.println(s); dis = new DataInputStream(s.getInputStream()); //初始化Socket的两个流。 dos = new DataOutputStream(s.getOutputStream()); System.out.println(v.size()); //打印此时登陆客户端的个数。 client = new Client(v.size(),dos, dis); //说明一个客户端连接上了,给个线程。只能定义一次。。。 v.addElement(client); //往向量里面添加一个客户端。 client.start(); //启动一个线程 System.out.println(getVectorSize());//打印此时登陆客户端的个数。 } catch (IOException e) { e.printStackTrace(); } } } catch (IOException e) { System.out.println("服务器启动失败!"); } } public static int getVectorSize() { return v.size(); } public static Vector<Client> getVector() { return v; } public static void main(String[] args) { new socketServer(); } } //每个客户端线程连接过去,则建立一个该对象 class Client extends Thread { int id; DataOutputStream dos; DataInputStream dis; public Client( int id,DataOutputStream dos, DataInputStream dis) { this.id=id; this.dis = dis; this.dos = dos; } public void run() { //启动时便执行该段代码! boolean flag = true; //只是一个标志 int m; while (flag) { try { String message = dis.readUTF(); //输入进来的流,简称输入流,拿到客户端的信息。 System.out.println(message); //后台打印出来 if (message.equals("exit")) {//如果接收到"exit"字符串,说明运行该线程的客户端断开了连接,则需退出该循环,退出线程 flag = false; //退出循环 socketServer.getVector().remove(this); //当客户端关闭时,从Vector里除去本对象 } else { m = socketServer.getVectorSize(); //返回共有多少个客户端目前。 for (int i = 0; i < m; i++) { //给每个客户端发送同样的信息。 socketServer.getVector().get(i).dos.writeUTF(message); //输出信息给每个客户端。 } } } catch (IOException e) { e.printStackTrace(); } } } }