⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chatserver.java

📁 聊天程序实现的功能可以是像QQ聊天程序那样点对点的对话
💻 JAVA
字号:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.net.*;
import java.io.*;
import java.util.*;

public class ChatServer extends JFrame {
  //以下为图形界面变量
  JPanel contentPane;
  JMenuBar jMenuBar1 = new JMenuBar();
  JMenu jMenuFile = new JMenu();
  JMenuItem jMenuFileExit = new JMenuItem();
  JMenu jMenuHelp = new JMenu();
  JMenuItem jMenuHelpAbout = new JMenuItem();
  static JLabel statusBar = new JLabel();
  BorderLayout borderLayout1 = new BorderLayout();
  JPanel jPanel1 = new JPanel();
  BorderLayout borderLayout2 = new BorderLayout();
  JLabel jLabel1 = new JLabel();
  static java.awt.List jList1 = new java.awt.List(13); 
  JScrollPane scrollpane=new JScrollPane(jList1);
  
  //以下为网络相关变量
  static Vector clients=new Vector(10);   //用vector向量数组存储连接客户变量
  static ServerSocket server=null;        //建立服务器socket
  static int active_connects=0;           //用来存储目前连接的客户数
  static Socket socket=null;               //用来存储一个套接字连接
  
  //ChatServer main method
   public static void main(String[] args)
  {
    try
    {
      UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    }
    catch(Exception e)
    {
      e.printStackTrace();
    }
        ChatServer ChatServer1=new ChatServer();      //实例化一个ChatServer类
	ChatServer1.show();
	System.out.println("Server starting ...");
	try
	   {
	    server=new ServerSocket(1234);      //使用端口1234初始化服务器套接字
	}
	catch(IOException e)
	   {
	    System.out.println("Error:"+e);
	}
	while(true)
	   {
	    if(clients.size()<10)       //当客户数小于10个时开始连接
		   {
		    try
			   {
			    socket=server.accept();   //用来存储连接上的客户socket
			    while(true){
                            if(socket!=null)
			    {
			    System.out.println(socket+"连接");    //在控制台打印客户连接信息
			    break;
			    }
			 }
			}
			catch(IOException e)
			   {
			    System.out.println("Error:"+e);
			}
			        Client c=new Client(socket);      //定义并实例化一个Client线程类,一个就对应一个客户连接
			        clients.addElement(c);             //加入clients数组中
				if(checkName(c))                  //调用checkName方法验证c的合法性
				   {
				    int connum=++ChatServer1.active_connects;  //定义connum来存储活动连接数
				    String constr="目前有"+connum+"客户相连";    //在状态栏里显示连接数
				    ChatServer1.statusBar.setText(constr);
				    Client listdata=(Client)clients.elementAt(clients.size()-1);   //将连接客户的socket信息存储进listdata数组
				    ChatServer1.jList1.addItem(listdata.ip+"连接");  //将客户socket信息写入list框
				    c.start();                                        //启动线程
				    notifyRoom();                                    //用notifyRoom方法来监视聊天室连接变化
					                                             //不断改变clients数组并刷新客户端信息
				}
				else
				   {
				    //如果名字不合法
                                   try{
				     c.dos.writeUTF("TAKEN");
				   }
                                   catch(IOException e)  {
                                    System.out.println("Error:"+e);
			           }
					disconnect(c);
				}
		}
		else                                   //如果clients数组超过了10个
		   {
			try{Thread.sleep(200);}
			catch(InterruptedException e)   {
                            System.out.println("Error:"+e);
			}
		}
	}//end of while
  }// end of main method

  /**Construct the frame*/
  public ChatServer()                          //ChatServer类的构造器用来初始化一些UI信息
  {
    enableEvents(AWTEvent.WINDOW_EVENT_MASK);
    try {
      jbInit();
    }
    catch(Exception e) {
      e.printStackTrace();
    }
  }

  /**Component initialization*/
  private void jbInit() throws Exception
  {
    contentPane = (JPanel) this.getContentPane();
    contentPane.setLayout(borderLayout1);
    contentPane.setBackground(Color.orange);
    this.setSize(new Dimension(400, 300));
    this.setTitle("聊天服务器端");
    statusBar.setText("目前的连接数为:");    
    jMenuFile.setText("File");
    jMenuFileExit.setText("Exit");
    jMenuFileExit.setBackground(Color.orange);
    jMenuFileExit.addActionListener(new ActionListener()  {
      public void actionPerformed(ActionEvent e) {
        jMenuFileExit_actionPerformed(e);
      }
    });
    jMenuHelp.setText("Help");
    jMenuHelpAbout.setText("About");
    jMenuHelpAbout.setBackground(Color.orange);
    jMenuHelpAbout.addActionListener(new ActionListener()  {
      public void actionPerformed(ActionEvent e) {
        jMenuHelpAbout_actionPerformed(e);
      }
    });
    jPanel1.setLayout(borderLayout2);
    jPanel1.setBackground(Color.orange);
    jLabel1.setText("服务器端连接客户");
    jMenuFile.add(jMenuFileExit);
    jMenuFile.setBackground(Color.orange);
    jMenuHelp.add(jMenuHelpAbout);
    jMenuHelp.setBackground(Color.orange);
    jMenuBar1.add(jMenuFile);
    jMenuBar1.add(jMenuHelp);
    jMenuBar1.setBackground(Color.orange);
    this.setJMenuBar(jMenuBar1);
    contentPane.add(statusBar, BorderLayout.SOUTH);
    contentPane.add(jPanel1, BorderLayout.CENTER);
    jPanel1.add(jLabel1,  BorderLayout.NORTH);
    jPanel1.add(scrollpane, BorderLayout.CENTER);	
  }//end of jbinit

  /**File | Exit action performed*/
  public void jMenuFileExit_actionPerformed(ActionEvent e)   //实现退出菜单方法
  {
    sendClients(new String("QUIT"));                         //向客户端发送断开连接信息
    closeAll();                                               //调用closeAll方法关闭所有连接
    System.exit(0);
  }

  /**Help | About action performed*/
  public void jMenuHelpAbout_actionPerformed(ActionEvent e)  //实现about对话框
  {
    ChatServer_AboutBox dlg = new ChatServer_AboutBox(this);
    Dimension dlgSize = dlg.getPreferredSize();
    Dimension frmSize = getSize();
    Point loc = getLocation();
    dlg.setLocation((frmSize.width - dlgSize.width) / 2 + loc.x, (frmSize.height - dlgSize.height) / 2 + loc.y);
    dlg.setModal(true);
    dlg.show();
  }
                                
  /**Overridden so we can exit when window is closed*/
  protected void processWindowEvent(WindowEvent e)          //实现关闭服务器端程序要进行的操作
  {
    super.processWindowEvent(e);
    if (e.getID() == WindowEvent.WINDOW_CLOSING) {
      jMenuFileExit_actionPerformed(null);
    }
  }

  /*以下实现各种方法*/
  public static void notifyRoom()                          //用来监视连接信息,不断刷新clients数组并刷新客户端用户列表信息
  {
     String people=new String("PEOPLE");
	 for(int i=0;i<clients.size();i++)
		{
	     Client c=(Client)clients.elementAt(i);
		 people=people+":"+c.name; 
	 }
	 sendClients(people);                                 //用sendClients方法向客户端发送信息
  }

  public static synchronized void sendClients(String msg)   //实现sendClients方法专用来向每个连接的客户端发送信息
  {
     for(int i=0;i<clients.size();i++)
		{
	     Client c=(Client)clients.elementAt(i);
		 c.send(msg);
	 }
  }

  public static void closeAll()                             //实现关闭所有连接信息
  {
     while(clients.size()>0)                                 //遍历clients数组删除所有连接客户信息
		{
	     Client c=(Client)clients.firstElement();
		 try
			{
		     c.socket.close();
		 }
		 catch(IOException e)
			{
		     System.out.println("Error:"+e);
		 }
		 finally
			{
		     clients.removeElement(c);
		 }
	 }//end of while
  }//end of closeAll method

  public static boolean checkName(Client newclient)         //实现检查连接客户的socket信息是否合法
  {
     for(int i=0;i<clients.size();i++)
		{
	     Client c=(Client)clients.elementAt(i);
		 if((c!=newclient)&&c.equals(newclient.name))
			 return false;
	 }
	 return(true);
  }//end of checkName method

  public static synchronized void disconnect(Client c)         //实现断开单个客户的方法
  {
     try
		{
		 jList1.addItem(c.ip+"断开连接");                      //在服务器端程序的list框中显示断开信息		 
                 int connum=--ChatServer.active_connects;                       //将连接数减1
                 String constr="目前有"+connum+"客户相连";    //在状态栏里显示连接数
	         statusBar.setText(constr);
                 c.send(new String("QUIT"));                    //向客户发送断开连接信息
		 c.socket.close(); 
	 }
	 catch(IOException e)
		{
	     System.out.println("Error:"+e);
	 }
	 finally
		{
	     clients.removeElement(c);                          //从clients数组中删除此客户的相关socket等信息
	 }
  }

}

class Client extends Thread                              //实现 Client线程类
{
    Socket socket;                                       //用来存储一个连接客户的socket信息
	String name;                                         //用来存储客户的连接姓名
	String ip;                                           //用来存储客户的ip信息
 	DataInputStream dis;                                 //用来实现接受从客户端发来的数据流
	DataOutputStream dos;                                      //用来实现向客户端发送信息的输出流
	public void send(String msg)                   //实现向客户端发送信息的方法
	  {
           try
           {
	   dos.writeUTF(msg);                                  //用输出流发送信息
	   }
           catch(IOException e)
                  {
               System.out.println("Error:"+e);
           }
	}

	public  Client(Socket s)                             //Client线程类的构造器
	  {
	   socket=s;                                           
	   try
		  {
	           dis=new DataInputStream(socket.getInputStream());  //存储特定客户socket的输入流接受s这个客户发送到服务器端的信息
		   dos=new DataOutputStream(socket.getOutputStream());      //存储特定客户socket的输出流发送服务器给s这个客户的信息
		   String info;
                   while(true){
                      info=dis.readUTF();                   //读取接受来的信息
		      if(info!=null) break;
                   }
		   StringTokenizer stinfo=new StringTokenizer(info,":");  //用StringTokenizer类来读取用":"分段字符
		   String head=stinfo.nextToken();                        //head用来存储类似于关键字的头信息
                   if(stinfo.hasMoreTokens())		   
		      name=stinfo.nextToken();                               //关键字后的第二段数据是客户名信息
		   if(stinfo.hasMoreTokens())
		      ip=stinfo.nextToken();                                  //关键字后的第三段数据是客户ip信息
		   System.out.println(head);                               //在控制台打印头信息
	   }
	   catch(IOException e)
		  {
	       System.out.println("Error:"+e);
	   }
	}//end of Client constrator

	public void run()                                           //线程运行方法
	  {
	   while(true)
		  {
	       String line=null;
		   try
			  {
		       line=dis.readUTF();                            //读取客户端发来的数据流
		   }
		   catch(IOException e)
			  {
		       System.out.println("Error"+e);
			   ChatServer.disconnect(this);
			   ChatServer.notifyRoom();
			   return;
		   }
		   if(line==null)    //客户已离开
			  {
			   ChatServer.disconnect(this);
			   ChatServer.notifyRoom();
			   return;
			  }
		   StringTokenizer st=new StringTokenizer(line,":");
		   String keyword=st.nextToken();
		   if(keyword.equals("MSG"))                          //如果关键字是MSG则是客户端发来的聊天信息
			  {
		       String msg=new String("MSG:");     //在服务器端再重新建立一个字符串
			   msg=msg+name;
			   msg=msg+st.nextToken("\0");
			   ChatServer.sendClients(msg);                   //再将某个客户发来的聊天信息发送到每个连接客户的聊天栏中
		   }
		   else if(keyword.equals("QUIT"))                   //如果关键字是QUIT则是客户端发来断开连接的信息
			  {
		       ChatServer.disconnect(this);                  //服务器断开与这个客户的连接
			   ChatServer.notifyRoom();                      //继续监听聊天室并刷新其他客户的聊天人名list
			   this.stop();                                   
		   }
	   }
	}
}  //end of class Client

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -