现在的位置: 首页 > 综合 > 正文

Socket群聊

2013年09月03日 ⁄ 综合 ⁄ 共 6655字 ⁄ 字号 评论关闭

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

 }
}

===========================客户端 socketClient.java===================================

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();     //先开服务器,再开客户端。代码入口处。
 }
}

==================================服务器 socketServer.java==============================

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

抱歉!评论已关闭.