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

📄 server.java

📁 java编写的一个客户端和服务器通信的软件
💻 JAVA
字号:
//Server.java
//作者:毛伟,贾桂卿,郭威
//基于TCP的聊天软件服务器端

import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.lang.*;

/*=============================================================
描述:实现服务器端界面
     创建一个套接字,绑定了8080端口。
     创建侦听线程,监测是否有客户端请求连接
     创建接收线程,接收客户端发来的数据
     创建发送线程,向客户端发送数据
==============================================================*/
public class Server extends JFrame
{
    public JTextField tField = new JTextField("输入");
    public JTextArea  tArea = new JTextArea("聊天记录:", 40, 20);
    public JScrollPane scrollArea = new JScrollPane(tArea,
			                          JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
				                  JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
    public JPanel buttons=new JPanel();
    public JButton  send = new JButton("发送"); 
    public JButton  clear = new JButton("清除"); 
    public JButton  disconn = new JButton("断开");
     
    public ServerSocket server;
    public Socket connectionSocket;
    
    public Object sendObj=new Object();

    public Thread waitConnect;     
    public Thread waitSend;
    public Thread waitRcv;
    
/*===============================================
描述:Server类的构造函数,用来创建服务器端界面
================================================*/   
    public Server(String title)
    {
	   super(title);
	   Container cp = getContentPane();
	   ButtonHandler handler = new ButtonHandler();
	   tField.addActionListener(handler);
	   send.addActionListener(handler);
	   clear.addActionListener(handler);
	   disconn.addActionListener(handler);                                          
	   BorderLayout layout=new BorderLayout();
	   cp.setLayout(layout);
	   cp.add(BorderLayout.WEST,scrollArea);
	   cp.add(BorderLayout.SOUTH,tField);
	   tField.setEnabled(false);
	   cp.add(BorderLayout.CENTER,buttons);
	   FlowLayout layout1 = new FlowLayout();
	   buttons.setLayout(layout1);
	   buttons.add(send);
	   send.setEnabled(false);
	   buttons.add(clear);
	   clear.setEnabled(false);
	   buttons.add(disconn);
	   disconn.setEnabled(false);
	   setSize(348, 200);
	   setVisible(true);	    	
    }
    
/*===============================================
描述:创建套接字,启动侦听线程
================================================*/      
    public void runServer()
    {
    	try
    	{
    	   server = new ServerSocket(8080);
    	   waitConnect = new Thread(new WaitForConnect(this));
    	   waitConnect.start();	   		   	
    	} 
   	    catch(IOException iException)
    	{
    	   tArea.append("\n打开通信端口失败!");
    	   iException.printStackTrace();
    	}
    }
    
/*===============================================
描述:启动服务器端接收和发送线程
================================================*/        
    public void initialSendRcvThread()
    {
    	tField.setEnabled(true);
    	send.setEnabled(true);
    	clear.setEnabled(true);
    	disconn.setEnabled(true);
    	waitSend = new Thread(new SendThread(this));
	    waitSend.start();
	    waitRcv = new Thread(new RcvThread(this));
	    waitRcv.start();   
    } 
    
/*===============================================
描述:Server类的入口点函数,也是整个服务器端的入口点
================================================*/        	  
    public static void main(String[] args)
    {
	   Server frame1=new Server("服务器");
	   frame1.addWindowListener(new WindowClose());
	   frame1.runServer();
    }
    
/*===============================================
描述:清除函数,在服务器端终止与客户端通信时,
     终止各类线程,关闭建立的套接字连接。
================================================*/      
    public void cleanAll() throws IOException
    {    	        
        if(waitRcv != null)
        {
    	   waitRcv.stop();
           waitRcv=null;	
        }     
        if(waitSend != null)
        {
           waitSend.stop();
           waitSend=null;	
        } 
        if(waitConnect != null)
        {
           waitConnect.stop();
           waitConnect=null;
        }
        
        tArea.append("\n断开与"+connectionSocket.getInetAddress().getHostName()+"连接!");
        tArea.setCaretPosition(tArea.getText().length());
        
        if(connectionSocket != null)
        {    		
           
           connectionSocket.close();
           connectionSocket=null;     	           	
        }
        if(server != null)
        {
        	server.close();
        	server = null;
        } 
        
	   send.setEnabled(false); 
	   clear.setEnabled(false);
	   disconn.setEnabled(false);             	  
    }
    
/*===============================================
描述:事件监听函数,监测并处理用户操作时引发的事件。
================================================*/         
    private class ButtonHandler implements ActionListener
    {
    	public void actionPerformed (ActionEvent e)
    	{
    	   if(e.getSource() == tField)
    	   {
    	   	   sendData(e.getActionCommand());
    	   	   synchronized(sendObj)
    	   	   {
    	   	      sendObj.notify();
    	   	   }
    	   }
    	   else if(e.getSource() == send)
    	   {
    	   	    sendData(tField.getText());
    	   	    synchronized(sendObj)
    	   	    {
    	   	        sendObj.notify();
    	   	    }
    	   }
    	   else if(e.getSource() == clear)
    	   {
    	   	   tArea.setText("聊天记录:");
    	   	   tField.setText("");
    	   }    	
    	   else if(e.getSource() == disconn)
    	   {
    	   	   try
    	   	   {
    	   	     cleanAll();
    	   	     runServer();		   	   	
    	   	   }
    	   	   catch (IOException io)
    	   	   {
    	   	   	 tArea.append("\n 关闭通信端口失败!");
    	   	   } 
    	   	   	   	 
    	   }  	
        }
    }
    
    public void sendData(String message)
    {
    	tArea.append("\n服务器>>"+message);
        tArea.setCaretPosition(tArea.getText().length());
    }      
}

/*===============================================
描述:用户关闭服务器端界面的事件处理类
================================================*/  
class WindowClose extends WindowAdapter
{
    public void windowClosing(WindowEvent e) 
    {
     	System.exit(0);
    }
}

/*===============================================
描述:侦听线程类,侦听指定的端口,监测是否有客户端
     请求连接
================================================*/  
class WaitForConnect implements Runnable
{
	Server serverObj;
	public WaitForConnect(Server serverObj)
	{
		this.serverObj=serverObj;
	}
	public void run()
	{  	
	    try
	    {
	       serverObj.tArea.append("\n等待连接!");
           serverObj.tArea.setCaretPosition(serverObj.tArea.getText().length());
    	   serverObj.connectionSocket = serverObj.server.accept();
    	   serverObj.tArea.append("\n与 " + serverObj.connectionSocket.getInetAddress().getHostName()+" 建立连接");
           serverObj.tArea.setCaretPosition(serverObj.tArea.getText().length());
    	   serverObj.initialSendRcvThread();    	
	    }
	    catch(EOFException eException)
    	{
    	   serverObj.tArea.append("\n客户端结束会话!");
    	   eException.printStackTrace();
    	}
    	catch(IOException iException)
    	{
    	   serverObj.tArea.append("\n连接意外失败!");
    	   iException.printStackTrace();
    	}
	    		
	}
}

/*===============================================
描述:接收线程类,接收来自客户端传来的数据
================================================*/  
class RcvThread implements Runnable
{
    ObjectInputStream input;
    Server serverObj;
    public RcvThread(Server serverObj)
    {
    	this.serverObj=serverObj;
    	try
    	{
    	    input = new ObjectInputStream(serverObj.connectionSocket.getInputStream());
        }
        catch(IOException iException)
    	{   	       
    		serverObj.tArea.append("\n初始化接收失败!");
    	}
    }
    public void run()
    {
    	while(true)
    	{  
    	    try
    		{
   	            String str = (String)input.readObject();   	   	    	
    	        serverObj.tArea.append("\n客户端>>"+str);
    	        serverObj.tArea.setCaretPosition(serverObj.tArea.getText().length());
    	    }
    	    catch(ClassNotFoundException e)
    	    {
    	    	serverObj.tArea.append("\n收到未知类型数据包!");
    	    }
    	    catch(IOException io)
    	    {
    	    }   	       
    	}
    }
}

/*===============================================
描述:发送线程类,向客户端发送用户需要传递的数据
================================================*/  
class SendThread implements Runnable
{  
    ObjectOutputStream output; 
    Server serverObj;  
    public SendThread(Server serverObj)
    {
    	this.serverObj=serverObj;
    	try
    	{
    		output=new ObjectOutputStream(serverObj.connectionSocket.getOutputStream());
    		output.flush();
    	}
    	catch(IOException iException)
    	{
    		iException.printStackTrace();
    		serverObj.tArea.append("\n初始化输出!");
    	}
    }
    public void run()
    {
    	while(true)
    	{
    	    synchronized(serverObj.sendObj)
    	    {
    	    	try
   	    	    {
    	    	   serverObj.sendObj.wait(0);
    	    	   output.writeObject(serverObj.tField.getText());	
    	    	}
    	    	catch(InterruptedException e)
    	    	{   	    	
  	            }
  	               catch(IOException io)
  	            {
  	            }
  	        }
    	}
    }
}

⌨️ 快捷键说明

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