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

📄 client.java

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

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

/*=============================================================
描述:实现客户端界面
     创建连接线程,向用户指定的运行服务器端软件的主机发出连接请求
     创建接收线程,接收服务器端发来的数据
     创建发送线程,向服务器端发送数据
==============================================================*/
public class Client extends JFrame
{
    private JTextField tField = new JTextField("输入");
    private JTextField ipAddress = new JTextField("输入服务器地址");
    private JTextArea  tArea = new JTextArea("聊天记录:", 40, 20);	
    private JScrollPane scrollArea = new JScrollPane(tArea,
			                          JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
				                  JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
    private JPanel buttons=new JPanel();
    private JButton  connect = new JButton("连接");
    private JButton  send = new JButton("发送"); 
    private JButton  clear = new JButton("清除"); 
    private JButton  quit = new JButton("退出");
     
    private Socket connectionSocket;
    private String chatServer;
    
    Object sendObj=new Object();
    Object connectObj=new Object();
     
    Thread waitSend;
    Thread waitRcv;   
    Thread waitConnect;
    
/*===============================================
描述:Client类的构造函数,用来创建客户端界面
================================================*/     
    public Client(String title)
    {
	   super(title);
	   Container cp = getContentPane();
	   ButtonHandler handler = new ButtonHandler();
	   tField.addActionListener(handler);
	   ipAddress.addActionListener(handler);
	   connect.addActionListener(handler);
	   send.addActionListener(handler);
	   clear.addActionListener(handler);
	   quit.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(ipAddress);
	   buttons.add(connect);
	   buttons.add(send);
	   send.setEnabled(false);
	   buttons.add(clear);
	   clear.setEnabled(false);
	   buttons.add(quit);
	   quit.setEnabled(false);
	   setSize(340, 218);
	   setVisible(true);	    	
    }
    
/*===============================================
描述:启动连接线程,请求服务器端连接
================================================*/     
    public void runClient()
    {
    	waitConnect = new Thread(new ConnectThread());
    	waitConnect.start(); 
    }
    
/*===============================================
描述:启动客户端接收和发送线程
================================================*/    
    public void InitilaSendRcvThread()
    {
        ipAddress.setEnabled(false);
    	connect.setEnabled(false);
    	tField.setEnabled(true);
    	send.setEnabled(true);
    	clear.setEnabled(true);
    	quit.setEnabled(true);	   	
	    waitSend = new Thread(new SendThread());
	    waitSend.start();
	    waitRcv = new Thread(new RcvThread());
	    waitRcv.start(); 	
    }
    
/*===============================================
描述:连接线程类,向服务器端发出连接请求
     用内部类实现
================================================*/      
    private  class ConnectThread implements Runnable 
    {
    	public ConnectThread()
    	{    		
    	}
    	public void run()
    	{
    	    synchronized(connectObj)
    	    {
    	    	try
   	    	    {
    	    	   connectObj.wait();    	    	   
    	           tArea.append("\n正在连接>>>>>>");
    	    	   connectionSocket = new Socket(InetAddress.getByName(chatServer),8080); 
    	           tArea.append("\n已连接到:"+connectionSocket.getInetAddress().getHostName());   	    	   
   	    	   	   InitilaSendRcvThread();
    	    	}
    	    	catch(InterruptedException e)
    	    	{   	    	
  	            }
  	            catch(EOFException eo)
  	            {
  	            	tArea.append("\n服务端终止连接!");
  	            }
  	            catch(IOException io)
  	            {
    	            io.printStackTrace();
    	            tArea.append("\n连接服务器失败!\n请退出,重新启动客户端!");
  	            }
  	         }
    	}
    	
    }
     
/*===============================================
描述:Client类的入口点函数,也是整个客户端的入口点
================================================*/     
    public static void main(String[] args)
    {
	   Client frame1=new Client("客户端");
	   frame1.addWindowListener(new WindowClose());
	   frame1.runClient();
    }
    
/*===============================================
描述:清除函数,在客户端退出与服务器端通信时,
     终止各类线程,关闭建立的套接字连接。
================================================*/      
    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;
        } 
        if(connectionSocket != null)
        {    		          
           connectionSocket.close();
           connectionSocket=null;     	           	
        }                	  
    }
    
/*===============================================
描述:发送线程类,向服务器端发送用户需要传递的数据
     用内部类实现
================================================*/     
    private class SendThread implements Runnable
    {  
        ObjectOutputStream output;   
    	public SendThread()
    	{
    		try
    		{
    		   output=new ObjectOutputStream(connectionSocket.getOutputStream());
    		   output.flush();
    		}
    		catch(IOException iException)
    		{
    			iException.printStackTrace();
    			tArea.append("\n初始化输出失败!");
    		}
    	}
    	public void run()
    	{
    	    while(true)
    	    {
    	    	synchronized(sendObj)
    	    	{
    	    	   try
   	    	       {
    	    	      sendObj.wait(0);
    	    	      output.writeObject(tField.getText());	
    	    	   }
    	    	   catch(InterruptedException e)
    	    	   {   	    	
  	               }
  	               catch(IOException io)
  	               {
  	               }
  	            }
    	    }
    	}
    }
    
/*===============================================
描述:接收线程类,接收来自服务器端传来的数据
     用内部类实现
================================================*/      
    private class RcvThread implements Runnable
    {
    	ObjectInputStream input;
    	public RcvThread()
    	{
    		try
    		{
    		  input = new ObjectInputStream(connectionSocket.getInputStream());
            }
            catch(IOException iException)
    	    {   	       
    			tArea.append("\n初始化输入失败!");
    	    }
    	}
    	public void run()
    	{
    	   while(true)
    	   {  
    	       try
    		   {
   	               String str = (String)input.readObject();   	   	    	
    	           tArea.append("\n服务器>>"+str);
    	           tArea.setCaretPosition(tArea.getText().length());
    	       }
    	       catch(ClassNotFoundException e)
    	       {
    	    	   tArea.append("\n未知格式的数据包!");
    	       }
    	       catch(IOException io)
    	       {
    	       }   	       
    	   }
    	}
    }
    
/*===============================================
描述:事件监听函数,监测并处理用户操作时引发的事件。
================================================*/      
    private class ButtonHandler implements ActionListener
    {
    	public void actionPerformed (ActionEvent e)
    	{
    	   if(e.getSource() == ipAddress)
    	   {
    	   	   chatServer = e.getActionCommand();
    	   	    synchronized(connectObj)
    	   	    {
    	   	        connectObj.notify();
    	   	    }
    	   }
    	   else if(e.getSource() == connect)
    	   {
    	   	   chatServer = ipAddress.getText();
    	   	    synchronized(connectObj)
    	   	    {
    	   	        connectObj.notify();
    	   	    }    	   	    
    	   }
    	   else 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() == quit)
    	   {
    	   	   try
    	   	   {
    	   	     cleanAll();
    	   	     System.exit(0);	   	   	
    	   	   }
    	   	   catch (IOException io)
    	   	   {
    	   	   	 tArea.append("\n关闭通信端口失败!");
    	   	   }     	   	   	   	 
    	   }  	
        }
    }
    
    public void sendData(String message)
    {
    	tArea.append("\n客户端>>"+message);
    } 
    
}

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

⌨️ 快捷键说明

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