socket java 多线程 聊天室

今天复习了socket网络编程,感觉并没有一开始接触时的难度了,顺带多线程也复习了一下下

依赖的jar包


主要有三个类,三个线程,分别是:

服务器端等待新客户端连接线程,

从客户端接收数据线程,

客户端接收服务端数据线程。

第一个是服务端Server:

public class Server implements Runnable {

	private int port = 8422;
	private List<ClientSocket> clients;
	private ServerSocket server;
	private static int clientId = 1;

	public static void main(String[] args) throws Exception {
		new Server();
	}

	public Server() throws IOException {
		server = new ServerSocket(10086);// 1024-65535的某个端口
		clients = new ArrayList<ClientSocket>();
		new Thread(this).start();
		System.out.println("server starting");
	}

	public void sendToAll(String message) throws IOException {
		for (ClientSocket client : clients) {
			client.sendMsg(message);
		}
	}

	@Override
	public void run() {
		try {
			while (true) {
				// 等待 客户端连接
				Socket client = server.accept();
				// 将连接的客户端初始化并运行
				ClientSocket clientSocket = new ClientSocket(client, this, clientId);
				clientId++;
				clientSocket.start();
				// 添加到客户端连接列表中
				clients.add(clientSocket);
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

客户端操作类:

public class ClientSocket extends Thread {

	private DataInputStream dis;
	private DataOutputStream dos;
	private Socket clientSocket;
	private Server server;
	private int clientId;

	public ClientSocket(Socket clientSocket, Server server, int clientId) throws Exception {
		super();
		this.clientSocket = clientSocket;
		this.server = server;
		this.clientId = clientId;
		this.dis = new DataInputStream(clientSocket.getInputStream());
		this.dos = new DataOutputStream(clientSocket.getOutputStream());
	}

	public void close() throws IOException {
		dis.close();
		dos.close();
		clientSocket.close();
	}

	public void sendMsg(String message) throws IOException {
		dos.writeUTF(message);
	}

	@Override
	public void run() {
		try {
			while (true) {
				server.sendToAll(dis.readUTF());
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}

客户端类:

public class Client extends JFrame implements Runnable {
	private JButton send;
	private JButton register;
	private JTextArea content;
	private JTextField message;
	private JTextField name;
	private JLabel label;
	private JLabel username;

	private DataOutputStream dos;
	private DataInputStream dis;
	private Socket socket;

	public static void main(String[] args) throws Exception {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					Client frame = new Client();
					Thread thread = new Thread(frame);
					thread.start();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	public Client() throws UnknownHostException, IOException {

		socket = new Socket("127.0.0.1", 10086);
		dis = new DataInputStream(socket.getInputStream());
		dos = new DataOutputStream(socket.getOutputStream());

		setLayout(new BorderLayout());
		send = new JButton("发送消息");
		register = new JButton("登录");
		content = new JTextArea();
		message = new JTextField(27);
		name = new JTextField(10);
		username = new JLabel();
		label = new JLabel("输入用户名");
		JPanel panel = new JPanel();
		JPanel panel2 = new JPanel();
		panel.setLayout(new BorderLayout());
		panel2.setLayout(new BorderLayout());
		panel.add(message, BorderLayout.WEST);
		panel.add(send, BorderLayout.EAST);
		panel2.add(label, BorderLayout.WEST);
		panel2.add(name, BorderLayout.CENTER);
		panel2.add(register, BorderLayout.EAST);
		add(content, BorderLayout.CENTER);
		add(panel, BorderLayout.SOUTH);
		add(panel2, BorderLayout.NORTH);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setSize(400, 400);
		setVisible(true);
		send.addActionListener(new sendListener());
		register.addActionListener(new sendListener());
	}

	private class sendListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {
			try {
				if(e.getSource().equals(send)){
					Message msg = new Message(Message.SendMSG,message.getText(),username.getText(),"");
					dos.writeUTF(msg.toJSON());
					message.setText("");
				}
				if(e.getSource().equals(register)){
					username.setText(name.getText());
				}
					
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		}
	}

	@Override
	public void run() {
		try {
			while (true) {
				Message message = Message.getInstance(dis.readUTF());
				content.append(message.from+" 说:" +message.getBody()+ "\n");
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}
}

用swing的界面....别嫌弃low,其中可以更好的实现,用单例管理线程池等等,可以自己实现,我把原理实现了就好嘻嘻。

中间的message是:

public class Message {
	public final static String LOGIN = "LOGIN";
	public final static String LOGOUT = "LOGOUT";
	public final static String SendMSG = "SENDMSG";
	String type;
	String body;
	String from;
	String to;
	
	public Message() {
		// TODO Auto-generated constructor stub
	}
	
	
	public Message(String type, String body, String from, String to) {
		super();
		this.type = type;
		this.body = body;
		this.from = from;
		this.to = to;
	}


	public static Message getInstance(String jsonStr)
	{
		Message instance = null;
		try { 
			JSONObject object = JSONObject.fromString(jsonStr); 
			instance = (Message) JSONObject.toBean(object, Message.class);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return instance;
	}
	
	public String toJSON()
	{
		JSONObject object = JSONObject.fromBean(this);
		return object.toString();
	}
	
	public String getType() {
		return type;
	}
	public void setType(String type) {
		this.type = type;
	}
	public String getBody() {
		return body;
	}
	public void setBody(String body) {
		this.body = body;
	}
	public String getFrom() {
		return from;
	}
	public void setFrom(String from) {
		this.from = from;
	}
	public String getTo() {
		return to;
	}
	public void setTo(String to) {
		this.to = to;
	}
	public static String getLogin() {
		return LOGIN;
	}
	public static String getLogout() {
		return LOGOUT;
	}
	
}

最后看效果:


猜你喜欢

转载自blog.csdn.net/qq_33683097/article/details/80877495
今日推荐