【无标题】GUI界面的Socket聊天室

 

要求:

(1)用Socket编程实现服务器端和客户端程序的编写。

(2)服务器端只负责好友列表的刷新,不负责客户端聊天信息的转发。


代码实现:

服务器端:

package 第十三周;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

import javax.swing.*;
import javax.swing.border.BevelBorder;
import javax.swing.border.Border;

public class Server extends JFrame {
	
	JLabel jl = new JLabel("开始监听9999端口!");
	
	JButton jb = new JButton("退出");
	
	JPanel jp_1 = new JPanel();
	JPanel jp_2 = new JPanel();
	JPanel jp_3 = new JPanel();
	
	ServerSocket s = null;
	
	Socket nsocket[] = new Socket[50];
	
	String str = "";
	StringBuilder sb = new StringBuilder(str);
	
	Border bevelBorder = new BevelBorder(BevelBorder.RAISED, Color.BLACK, Color.BLACK, Color.BLACK, Color.BLACK);
	
	public Server() {
		super("Socket聊天室服务器端");
		init();
		this.setSize(350, 250);
		this.setLocationRelativeTo(null);
		this.setDefaultCloseOperation(this.EXIT_ON_CLOSE);
		this.setVisible(true);
	}
	
	public void init() {
		jp_1.setLayout(new BorderLayout());
		jp_2.setBorder(bevelBorder);
		jp_3.add(jb);
		jl.setHorizontalAlignment(JLabel.RIGHT);
		
		jp_1.add(jl, BorderLayout.NORTH);
		jp_1.add(jp_2);
		jp_1.add(jp_3, BorderLayout.SOUTH);
		
		jb.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				int i = JOptionPane.showConfirmDialog(jb, "您确定要退出吗?");
				if(i == 0) {
					System.exit(0);
				}
			}
		});
		
		this.add(jp_1);
	}
	
	public static void main(String[] args) throws Exception {
		new Server().MoreServer();
	}
	
	public void MoreServer() {
		try {
			s = new ServerSocket(9999);
			System.out.println("服务器已经开启...");
			
			int i = 0;
			while(true) {
				Socket socket = s.accept();
				int j = 0;
				nsocket[i++] = socket;
				String addr = socket.getInetAddress().getHostAddress() + ":" + socket.getPort();
				System.out.println("客户" + addr + "访问!");
				sb.append(addr).append(",");
				str = sb.toString();
				for(j = 0; j < i; j++) {
					PrintStream ps = new PrintStream(nsocket[j].getOutputStream());
					ps.println(str);
				}
				new ServerReaderThread1(socket, nsocket, str, i).start();
			}
		} catch (IOException e) {
			e.printStackTrace();
		} 
	}	
	
	class ServerReaderThread1 extends Thread {
		Socket socket;
		Socket nsocket[];
		String addr;
		Scanner sc;
		int cnt;
		
		public ServerReaderThread1(Socket socket, Socket nsocket[], String str, int cnt) {
			super();
			this.socket = socket;
			this.nsocket = nsocket;
			addr = str;
			this.cnt = cnt;
		}
	
		@Override
		public void run() {
			try {
				sc = new Scanner(socket.getInputStream());
				while(true) {
					String str = sc.nextLine();
					
					if("exit".equalsIgnoreCase(str)) {
						addr = sc.nextLine();
						String arr[] = addr.split(",");
						
						int j = 0;
						for(int i = 0; i < arr.length; i ++) {
							if(nsocket[i] == socket) {
								j = i;
							}
						}
						
						for(int i = j; i < arr.length; i++) {
							if(i != arr.length - 1) {
								arr[i] = arr[i + 1];
							}
							else {
								arr[i] = "";
							}
						}
						
						StringBuilder sb1 = new StringBuilder();
						for(int i = 0; i < arr.length - 1; i++) {
							sb1.append(arr[i]).append(",");
						}
						sb = sb1;
						addr = sb1.toString();
						for(int p = 0; p < nsocket.length; p++) {
							PrintStream ps = new PrintStream(nsocket[p].getOutputStream());
							ps.println(addr);
						}
						break;
					}
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}	
}

	

 

 客户端:

import java.awt.BorderLayout;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
import java.util.Vector;

import javax.swing.*;
import javax.swing.border.TitledBorder;
 
public class ChatClient extends JFrame {
	
	Vector v = new Vector();
	
	Socket socket;
	
	JList<String> jList = new JList<String>(v);
	
	JLabel jl = new JLabel("连接到127.0.0.1:9999端口!");
	
	JTextArea jta_1 = new JTextArea(10, 25);
	JTextArea jta_2 = new JTextArea(2, 42);
	
	JButton jb_sent = new JButton("发送");
	JButton jb_clear = new JButton("清空");
	
	JPanel jp_1 = new JPanel();
	JPanel jp_2 = new JPanel();
	JPanel jp_3 = new JPanel();
	JPanel jp_4 = new JPanel();
	
	String s1;
	
	public ChatClient() throws Exception {
		super("聊天室客户端");
		init();
		this.setLocationRelativeTo(null);
		this.setDefaultCloseOperation(this.EXIT_ON_CLOSE);
		this.setVisible(true);
	}
	
	public void init() {
		//组装视图
		this.setLayout(new BorderLayout());
		this.setSize(500, 380);
		
		//组装顶部
		jList.setFixedCellWidth(160);
		jList.setFixedCellHeight(37);
		TitledBorder tb_1 = new TitledBorder("好友列表");
		jList.setBorder(tb_1);
		jp_1.add(jList);
		
		
		
		TitledBorder tb_2 = new TitledBorder("聊天记录");
		jta_1.setBorder(tb_2);
		jl.setHorizontalAlignment(JLabel.RIGHT);
		jp_2.setLayout(new BorderLayout());
		jp_2.add(jl, BorderLayout.NORTH);
		jp_2.add(new JScrollPane(jta_1));
		
		//组装底部
		TitledBorder tb_3 = new TitledBorder("请输入文字:");
		jta_2.setBorder(tb_3);
		jp_4.add(jb_sent);
		jp_4.add(jb_clear);
		
		Box vBox = Box.createVerticalBox();
		vBox.add(jta_2);
		vBox.add(jp_4);
		jp_3.add(vBox);
		
		this.add(jp_1, BorderLayout.WEST);
		this.add(jp_2);
		this.add(jp_3, BorderLayout.SOUTH);
	}
	
	public static void main(String[] args) throws Exception {
			new ChatClient().MoreClient();
	}
	
	public void MoreClient() throws Exception {
		Socket socket = new Socket("127.0.0.1", 9999);
		Scanner sc = new Scanner(System.in);
		PrintWriter pm = new PrintWriter(socket.getOutputStream());;
		
		this.addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				pm.println("exit");
				pm.flush();
				pm.println(s1);
				pm.flush();
			}
		});
		
		while(true) {
			Scanner sc1 = new Scanner(socket.getInputStream());
			s1 = sc1.nextLine();
			if(!v.contains(s1)) {
				add(s1);
			}
		}
	}
	
	public void add(String str) {
		v.clear();
		String arr[] = new String[50];
		arr = str.split(",");
		for(String s : arr) {
			v.addElement(s);
			jList.setListData(v);
		}
	}
}

 

 

运行过程:

(1)首先启动服务端

caafe4be5a694e4b97858debc5fa3851.png

 

(2)接着启动第一个客户端,好友列表刷新出第一个在线用户

998a6e9624474eefaae3e20c4aba8c2e.png

 

(3)再启动第二个客户端,两个客户端的好友列表此时都有两个在线用户

76e0c02bc4034682aeaf90c3d520f0ea.png

(4)退出第二个启动的客户端,此时第一个启动的客户端的列表中只剩一个在线用户

805732c184a349019fe42dbeea6edfea.png

 (5)再启动第三个客户端,此时两个在线的客户端的好友列表又存在两个在线用户

 63b90837de4c4efcb66b077cad4e941d.png

 

(6)运行结果大致如上。 

 

 

  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值