题目:

java实验9(图1)

java实验9(图2)

代码:

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.*;
import java.net.*;
import java.util.*;

import javax.swing.*;


//服务器窗口
//***********************************************************************************************************************
class ServiceWin extends JFrame{
	private JTextArea output;
	private JButton send;
	public ServiceWin(){
		JFrame jf = new JFrame("服务器"); // 实例化一个JFrame对象
		jf.setLayout(null);
		Container container = jf.getContentPane(); // 获取一个容器
		jf.setVisible(true); // 使窗体可视
		jf.setBounds(650,10,510, 400); // 设置窗体大小
		jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
		jf.setResizable(false);
		send = new JButton("创建用户");
		send.setBounds(155, 320, 200, 30);
		container.add(send);
		
		output =  new JTextArea("");
		output.setBounds(15, 10, 465, 300);
		
		output.setLineWrap(true);
		output.setColumns(10);
		output.setFont(new Font("宋体",0,25));
		output.setBackground(Color.white);
		container.add(output);
	}
	
	//传出数据
	public JTextArea Out(){
		return output;
	}
	public JButton Send(){
		return send;
	}
}
//***********************************************************************************************************************


//用户窗口
//***********************************************************************************************************************
class UserWin extends JFrame {
	private static final long serialVersionUID = 1L;
    // 定义一个类继承JFrame类
	private JTextField input;
	private JTextArea output;
	private JButton send;
	private JButton quit;
	private Container container;
	private JFrame jf;
	public void CreateJFrame(String title) { // 定义一个CreateJFrame()方法
		jf = new JFrame(title); // 实例化一个JFrame对象
		jf.setLayout(null);
		container = jf.getContentPane(); // 获取一个容器
		jf.setVisible(true); // 使窗体可视
		//获取屏幕宽高
		Toolkit toolkit = Toolkit.getDefaultToolkit();
		Dimension screen = toolkit.getScreenSize();
		int x = (int) ((Math.random()*screen.getWidth())%(screen.getWidth()*0.8));
		int y = (int) ((Math.random()*screen.getHeight())%(screen.getHeight()*0.8));
		jf.setBounds(x,y,500, 450); // 设置窗体位置 大小
		
        send = new JButton("发送");
		send.setBounds(375, 370, 100, 30);
		container.add(send);
		
		quit = new JButton("退出");
		quit.setBounds(15, 10, 450, 30);
		container.add(quit);

		input = new JTextField();
		input.setBounds(10, 370, 350, 30);
		container.add(input);
		
		output =  new JTextArea("");
		output.setBounds(10, 60, 465, 300);
		
		output.setLineWrap(true);
		output.setColumns(10);
		output.setFont(new Font("宋体",0,25));
		output.setBackground(Color.white);
		container.add(output);
		// 设置窗体不可调节大小
		jf.setResizable(false);
	
	}
	
	
	//送出数据
	public JTextField INput(){
		return input;
	}
	public JTextArea OUTput(){
		return output;
	}
	public JButton Quit(){
		return quit;
	}
	public JButton Send(){
		return send;
	}
	
	//关闭窗口
	public void Close(){
		jf.dispose();
	}
	
}


//***********************************************************************************************************************


//用户线程
//***********************************************************************************************************************
class userThr implements Runnable{
    private Socket socket;
    private PrintWriter write;
    private UserWin userwin;
    private String temp = "";
    private String temps = "";
    private int falg = 0;
	public void run() {
		userwin = new UserWin();  //创建窗口   并且获取数据
		userwin.CreateJFrame("用户");
		connet();   //创建连接
		//绑定点击事件
		userwin.Send().addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent arg0) {
				if(userwin.INput().getText().length() == 0) {
					JOptionPane.showMessageDialog(null, "不能发送空白消息!"); //不能发送空白消息
				}else{
					temp = userwin.INput().getText();
					if(temp.length()!=0) write.println(temp);
					temps+=temp+'\n';
					userwin.OUTput().setText(temps);
					userwin.INput().setText("");
				}}});
		
		//绑定退出事件
		userwin.Quit().addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent arg0) {
				  
				   try {
					 if(socket != null)
					         socket.close();
					 if(write != null)
					         write.close();
					//关闭窗口
					userwin.Close();
					falg = 1;
					return;
				   } catch (IOException e) {System.out.println("关闭流出问题");e.printStackTrace();}
			}});
		
		//循环
		while(true){
			if(falg == 1) break;
		}
	}
	//连接
	private void connet(){
		userwin.OUTput().append("尝试链接!\n");
		try {
			socket = new Socket("127.0.0.1",8919);
			write = new PrintWriter(socket.getOutputStream(),true);
			userwin.OUTput().append("链接成功!\n");
		} catch (Exception e) {
			// TODO: handle exception
			System.out.println("链接出问题");
		}
	}
}
//***********************************************************************************************************************

//主类
//***********************************************************************************************************************
public class lixiao9 implements Runnable {
	private JTextArea output;
	private JButton great;
	//用Vector存储
	private Vector<Socket> socket;
	private Vector<BufferedReader> reader;
	private ServerSocket server;
	private Vector<userThr> User = new Vector<userThr>();
	public void run() {
		//定义服务器窗口  并获取数据
		final ServiceWin service = new ServiceWin();
		output = service.Out();
		great = service.Send();
		socket = new Vector<Socket>();
		reader = new Vector<BufferedReader>();
		
		//绑定点击事件  创建用户
		great.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent arg0) {
				User.add(new  userThr());
				Thread used=new Thread(User.lastElement());
				used.start();
			}
		});
		//在8918端口监听
		try {
			server = new ServerSocket(8919);
			while(true){  //不断循环 如果有客户连接 创建一个新线程
				synchronized ("") {
					socket.add(server.accept());
					Thread.sleep(1000);	
				}
				new Thread() {
					BufferedReader readers;
		              public void run() {
		            	  try {
								reader.add(new BufferedReader(new InputStreamReader(socket.lastElement().getInputStream())));
								readers = reader.lastElement();
							} catch (IOException e1) {e1.printStackTrace();}
		            	  while(true){
                    		  try {
		            			  String s=readers.readLine();
		            			  if( s== null){
		            				  output.append("-----------一个用户退出------------\n"); 
		            				  break;
		            			  }
								  if(s.length() != 0) output.append(s+'\n');
		            			} catch (Exception e) {
		            				System.out.println("流出问题");
		            			}
		            	  }
		              }	
				 }.start();
				
			}
		} catch (Exception e) {System.out.println("端口监听问题");}
		
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		lixiao9 MAIN=new lixiao9();
		Thread ma=new Thread(MAIN);
		ma.start();
	}
}
//***********************************************************************************************************************

思考:

     这次呢,比较久,一直被换行符坑,在服务器端读取数据时,调用依次read Line();便会把客户端输入流读出来,所以在判断的时候,可以先把readLine()结果存下来,不然你第二次调用时,你会得到null,导致服务器端不能输出任何东西;这次代码比较粗糙,稍后会更新一个比较全的代码;