Java Socket 复习

1.server

package www10m23chat;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

public class ChatServer {
	// 保留每一个聊天客户对应的Socket对象
	private Set<Socket> clients;
	private List<String> list;
	public void init() {
		list=new ArrayList<String>();
		clients = new HashSet();
		try {  
			ServerSocket ss = new ServerSocket(9856);
			System.out.println("Chat Server started.");
			while (true) {
				Socket socket = ss.accept();
				clients.add(socket);
				//从客户端socket.getInputStream中获取输入流
				BufferedReader br=new BufferedReader(
						new InputStreamReader(socket.getInputStream()));
				//读取 username
				String username=br.readLine();
				System.out.println(username);
				list.add(username);
				String str="";
				for (int i = 0; i < list.size(); i++) {
					str+=list.get(i)+",";
				}
				str=str.substring(0, str.length()-1);
				for (Socket s : clients) {
					PrintWriter pw=new PrintWriter(s.getOutputStream());
					pw.println("login#"+str);
					pw.flush();
				}
				System.out.println(socket.getInetAddress());
				ChatServerThread cst = new ChatServerThread(socket, clients,list);
				cst.start();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		new ChatServer().init();
	}
}

class ChatServerThread extends Thread {
	private Socket socket;

	private Set<Socket> clients;// 所有聊天用户socket对象的集合

	private List<String> list;
	
	public ChatServerThread(Socket s, Set clients,List<String> list) {
		this.socket = s;
		this.clients = clients;
		this.list=list;
	}

	// 反复接受这个客户发过来的聊天内容
	// 接受到聊天内容后,把这个聊天内容广播给所有的聊天用户
	// 这个用户退出了,不用接受这个用户的输入,这个线程结束
	// 从用户Socket的集合中,移除当前Socket对象
	public void run() {
		try {
			InputStream is = socket.getInputStream();
			InputStreamReader isr = new InputStreamReader(is);
			BufferedReader br = new BufferedReader(isr);
			while (true) {
				String s = br.readLine();
				if (s.indexOf("#exit") != -1) {
					String[] arr = s.split("#");
					clients.remove(socket);
					is.close();
					socket.close();
					String ss=arr[2] + ",exit";
					System.out.println(ss);
//					BASE64Encoder en=new BASE64Encoder();
//					ss=en.encode(ss.getBytes());
					broadcast(ss, clients);
					list.remove(arr[2]);
					String str="";
					for (int i = 0; i < list.size(); i++) {
						str+=list.get(i)+",";
					}
					if(str.length()!=0){
						str=str.substring(0, str.length()-1);
						list.remove(arr[2]);
						for (Socket c : clients) {
							PrintWriter pw=new PrintWriter(c.getOutputStream());
							pw.println("exit#"+str);
							pw.flush();
						}
					}
					break;
				}

				broadcast(s, clients);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	// 把当前用户输入聊天内容,广播给所有的聊天用户
	private void broadcast(String str, Set clients) {
//		for (Socket s : clients) {
		Iterator it=clients.iterator();
		while(it.hasNext()){
			Socket s=(Socket) it.next();
			try {
				PrintWriter pw = new PrintWriter(s.getOutputStream());
				pw.println(str);
				pw.flush();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

}

2.client

package www10m23chat;
import java.awt.BorderLayout;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.swing.JOptionPane;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

public class ChatClient implements ActionListener {
	private JFrame jf;

	private String serverIp;

	private String username;

	private Socket socket;

	private JTextField jtf;

	private PrintWriter pw;

	private int port = 9856;

	private JTextArea jta;

	private RefreshMessageThread rmt;
	
	private JList userList;

	
	public void init() {
		userList=new JList();
		userList.setFont(new Font("宋体", Font.BOLD, 20));
		jf = new JFrame("聊天客户端 v1.0");

		// serverIp = JOptionPane.showInputDialog(jf, "请输入聊天服务器的地址");
		// serverIp="172.16.1.10";
		serverIp = "127.0.0.1";
		username = JOptionPane.showInputDialog(jf, "请输入聊天昵称");

		jta = new JTextArea(20, 50);
		jta.setEditable(false);
		Font font = new Font("宋体", Font.BOLD, 24);
		jta.setFont(font);
		jta.setText("欢迎" + username + "使用我们的聊天程序,祝您聊的愉快!\n");
		JScrollPane jsp = new JScrollPane(jta);
		jf.add(jsp, BorderLayout.CENTER);
  
		JPanel jp = new JPanel();
		JLabel ja = new JLabel(username + "说:");
		jtf = new JTextField(50);

		JButton jb = new JButton("提交");
		jb.addActionListener(this);
		jp.add(ja);
		jp.add(jtf);
		jp.add(jb);
		
		JButton jb2=new JButton("抖动");
		jb2.addActionListener(new ActionListener(){

			public void actionPerformed(ActionEvent e) {
				PrintWriter pw;
				try {
					pw = new PrintWriter(socket.getOutputStream());
				
					pw.println("doudong");
					pw.flush();
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}
			
		});
		
		jp.add(jb2);
		jf.add(jp, BorderLayout.SOUTH);
		
		
		
		jtf.addActionListener(this);

		jf.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				// 当关闭聊天窗口,弹出退出的确认框
				int i = JOptionPane.showConfirmDialog(jf, "真退出吗?");
				// 当前的聊天用户真的退出
				if (i == JOptionPane.YES_OPTION) {
					// #exit#username
					pw.println("#exit#" + username);
					pw.flush();
					rmt.setStop(true);
					try {
						Thread.sleep(200);
					} catch (InterruptedException e2) {
						e2.printStackTrace();
					}
					pw.close();
					try {
						socket.close();
					} catch (IOException e1) {
						e1.printStackTrace();
					}
					System.exit(1);
				}
			}
		});
		JScrollPane js=new JScrollPane(userList);
		jf.add(js,BorderLayout.EAST);

		jf.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
		jf.pack();
		jf.setVisible(true);

	}

	// 用户按下提交按钮,执行这个方法
	public void actionPerformed(ActionEvent e) {
		String message = jtf.getText();
		// 判断输入聊天是否为空,弹出警告框
		if (message.equals("")) {
			JOptionPane.showMessageDialog(jf, "请先输入聊天内容");
			return;
		}

		if (message.equals("doudong")) {
			pw.println(message);
			pw.flush();
			jtf.setText("");
			return;
		}

		SimpleDateFormat sdf = new SimpleDateFormat("MM/dd HH:mm:ss");

		// 聊天内容不为空,把该内容发送给服务器
		message = username + "说:" + message + "\t[" + sdf.format(new Date())
				+ "]";

//		try {
//			BASE64Encoder en = new BASE64Encoder();
//			message = en.encode(message.getBytes("GBK"));
//
//		} catch (UnsupportedEncodingException e1) {
//			// TODO Auto-generated catch block
//			e1.printStackTrace();
//		}

		pw.println(message);
		pw.flush();

		jtf.setText("");
	}

	// 用来建立与聊天服务器的网络连接
	public void connect() {
		try {
			socket = new Socket(serverIp, port);
			pw = new PrintWriter(socket.getOutputStream());
			pw.println(username);
			pw.flush();
			BufferedReader br=new BufferedReader(
					new InputStreamReader(socket.getInputStream()));
			String message=br.readLine();
			System.out.println(message.split("#")[1]);
			String sss=message.split("#")[1];
			userList.setListData(sss.split(","));
			rmt = new RefreshMessageThread(jta, socket,userList);
			rmt.start();

		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		ChatClient cc = new ChatClient();
		cc.init();
		cc.connect();
	}
}

// 用来实时接收服务器广播的聊天内容
class RefreshMessageThread extends Thread {
	private JTextArea jta;

	private Socket socket;

	private boolean stop = false;
	
	private JList userList;

	public RefreshMessageThread(JTextArea jta, Socket socket,JList userList) {
		this.jta = jta;
		this.socket = socket;
		this.userList=userList;
	}

	public void setStop(boolean stop) {
		this.stop = stop;
	}

	public void run() {
		try {
			InputStream is = socket.getInputStream();
			InputStreamReader isr = new InputStreamReader(is);
			BufferedReader br = new BufferedReader(isr);
			while (!stop) {
				Thread.sleep(100);
				// 服务器没有广播内容,这个地方一直等待
				// 得到广播的内容,追加到文本域上显示
				String message = br.readLine();
				if (message != null) {
					System.out.println(message+"-------------");
					if(message.startsWith("login#")||message.startsWith("exit#")){
						System.out.println(message.split("#")[1]);
						String sss=message.split("#")[1];
						System.out.println(sss+"++++sssssssssssssssssssss");
						userList.setListData(sss.split(","));
						continue;
					}
					
					
					if ("doudong".equals(message)) {
						JFrame jf=(JFrame) JOptionPane.getFrameForComponent(jta);
//						((JFrame) (jta.getTopLevelAncestor()))
//						.setAlwaysOnTop(true);
						jf.setExtendedState(JFrame.NORMAL);
						jf.setAlwaysOnTop(true);

						int x = jf.getX();
						int y = jf.getY();
						for (int i = 0; i < 20; i++) {
							if ((i & 1) == 0) {
								x += 3;
								y += 3;
							} else {
								x -= 3;
								y -= 3;
							}
							jf.setLocation(x, y);

//							
							try {
								Thread.sleep(50);
							} catch (InterruptedException e1) {
								e1.printStackTrace();
							}

							((JFrame) (jta.getTopLevelAncestor()))
									.setAlwaysOnTop(false);
						}

						continue;

					}

//					BASE64Decoder de = new BASE64Decoder();
//					message = new String(de.decodeBuffer(message), "GBK");

					System.out.println(message);
					jta.append("\n" + message);

					jta.select(jta.getText().length(), jta.getText().length());
				}
			}
			br.close();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值