在厦门的第一阶段给我们复习了JAVASE基础,第一阶段的小玩具叫我们自选题材,我自己选了聊天室这个内容,这个小玩具无论是线程,还是网络编程,都会涉及到,比较有综合性,所以我选了这个;
这是我的包体结构:
类包,JDBC工具包,界面包
首先讲一下思路,聊天室是一个端对端的数据传输平台,然而Socket一般来说只是个点对点的数据传输,这样的话,为了解决这个问题,我将所有的接入本服务器的客户端都给了一个List接收,离开时通过语句判断将他移除,有客户端发消息时便将信息广播给在List中的客户端,代码如下:
public class Server { int port; List<Socket> clients;//接入本服务器的客户端 ServerSocket server; public static void main(String[] args) { new Server(); } public Server() { try { port = 8080; clients = new ArrayList<Socket>(); server = new ServerSocket(port); System.out.println("..........."); while (true) { //时刻监测是否有客户端接入,接入则加入 Socket socket = server.accept(); System.out.println(socket); clients.add(socket); Mythread mythread = new Mythread(socket); mythread.start(); } } catch (Exception ex) { ex.printStackTrace(); } } class Mythread extends Thread { Socket ssocket; private BufferedReader br; private PrintWriter pw; public String msg; public Mythread(Socket s) { ssocket = s; } public void run() { //该方法用于监测是否有客户端传来消息 try { br = new BufferedReader(new InputStreamReader( ssocket.getInputStream())); msg = "欢迎进入聊天室!当前聊天室有【" + clients.size() + "】人"; sendMsg(); while ((msg = br.readLine()) != null) { msg = "【" + ssocket.getInetAddress() + "】" + msg; sendMsg(); } } catch (Exception ex) { ex.printStackTrace(); } } public void sendMsg() { try {// 监测发内容是否是离开格式 System.out.println(msg); String[] aaStrings = msg.split("-"); for (int i = 0; i < clients.size(); i++) { if (clients.get(i).toString().split(",")[0] .equals(aaStrings[1].split(",")[0])) { System.out.println("有人离开了聊天室!!"); clients.remove(i); break; } } } catch (Exception ex) { for (int i = 0; i < clients.size(); i++) {//遍历发送信息 try { pw = new PrintWriter(clients.get(i).getOutputStream(), true); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } pw.println(msg); pw.flush(); } } } } }
将这个问题解决了,客户端便也不是个难题了,我把发送消息封装在了Client中:
public class ClientDao { Socket socket; String message; public ClientDao(String message, Socket socket) { this.message = message; this.socket = socket; } //发送消息 public void send(String message, Socket socket) { OutputStream os; try { //获取socket的输出流 os = socket.getOutputStream(); BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os)); //将消息发送出去 bw.write(message); //换行 bw.newLine(); bw.flush(); // 清空缓存 } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
由于我需要将用户信息传输给下一个页面,于是我将窗口的构造方法重写了具体实现代码如下:
public class TalkClient extends JFrame { /** * */ private static final long serialVersionUID = 1L; private JPanel contentPane; private JTextField sendText; private JTextArea jta; public static boolean connect = false; // 客户端是否连接 ClientDao cDao; public int port = 8080; Socket socket = null; String msg2; /** * Launch the application. */ public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { try { TalkClient frame = new TalkClient(); frame.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } }); } /** * Create the frame. */ public TalkClient() { addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { msg2= "asdasd" +"-"+socket+"-"+"close"; cDao=new ClientDao(msg2, socket); cDao.send(msg2, socket); } }); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setBounds(100, 100, 505, 477); contentPane = new JPanel(); contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); setContentPane(contentPane); contentPane.setLayout(null); sendText = new JTextField(); sendText.setBounds(120, 257, 343, 43); contentPane.add(sendText); sendText.setColumns(10); JLabel label = new JLabel("\u6D88\u606F\u8BB0\u5F55\uFF1A"); label.setBounds(34, 15, 76, 15); contentPane.add(label); jta= new JTextArea(); JScrollPane jsp = new JScrollPane(jta); jsp.setBounds(120, 10, 343, 220); jsp.setVerticalScrollBarPolicy( JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); getContentPane().add(jsp); JLabel label_1 = new JLabel("\u5F85\u53D1\u9001\u6D88\u606F\uFF1A"); label_1.setBounds(34, 271, 76, 15); contentPane.add(label_1); JLabel namelb = new JLabel(""); namelb.setBounds(90, 354, 54, 15); contentPane.add(namelb); JButton sendBtn = new JButton("\u53D1\u9001"); sendBtn.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { //發送消息 //msg2=sendText.getText().toString().trim(); //jta.append("\n客户端说:" + sendText.getText().toString()); msg2 = sendText.getText().toString() ; //System.out.println(socket); cDao=new ClientDao(msg2, socket); cDao.send(msg2, socket); } }); sendBtn.setBounds(301, 350, 93, 23); contentPane.add(sendBtn); connectServer(); new Thread(new Runnable() { public void run() { try { BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); String msg1; while ((msg1 = br.readLine()) != null) { jta.append("\n"+":"+msg1); } } catch (Exception e) { e.printStackTrace(); } } }).start(); } public TalkClient(final User user) { // TODO Auto-generated constructor stub setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setBounds(100, 100, 505, 477); contentPane = new JPanel(); contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); setContentPane(contentPane); contentPane.setLayout(null); sendText = new JTextField(); sendText.setBounds(120, 257, 343, 43); contentPane.add(sendText); sendText.setColumns(10); JLabel label = new JLabel("\u6D88\u606F\u8BB0\u5F55\uFF1A"); label.setBounds(34, 15, 76, 15); contentPane.add(label); jta= new JTextArea(); JScrollPane jsp = new JScrollPane(jta); jsp.setBounds(120, 10, 343, 220); jsp.setVerticalScrollBarPolicy( JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); getContentPane().add(jsp); JLabel label_1 = new JLabel("\u5F85\u53D1\u9001\u6D88\u606F\uFF1A"); label_1.setBounds(34, 271, 76, 15); contentPane.add(label_1); JLabel namelb = new JLabel(""); namelb.setBounds(90, 354, 54, 15); contentPane.add(namelb); JButton sendBtn = new JButton("\u53D1\u9001"); sendBtn.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { //發送消息 //jta.append(user.getUserName() + sendText.getText().toString()); msg2 =user.getUserName()+"说:"+ sendText.getText().toString() ; //System.out.println(socket); cDao=new ClientDao(msg2, socket); cDao.send(msg2, socket); } }); sendBtn.setBounds(301, 350, 93, 23); contentPane.add(sendBtn); connectServer(); namelb.setText(user.getUserName()); new Thread(new Runnable() { public void run() { try { BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); String msg1; while ((msg1 = br.readLine()) != null) { System.out.println("xiaoxi"+msg1); jta.append("\n"+msg1); } } catch (Exception e) { e.printStackTrace(); } } }).start(); addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { msg2=user.getUserName()+"-"+socket+"-"+"close"; cDao=new ClientDao(msg2, socket); cDao.send(msg2, socket); } }); } public boolean connectServer() { try { // 获取输入的IP地址,并且进行连接 socket = new Socket("192.168.6.196", 8080); jta.append("\n连接服务器成功!"); connect = true; return true; } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); jta.append("\n连接失败"); } return false; } }
这里我就不将那些JDBC,贴上来了,基本上这样就好了
扫描二维码关注公众号,回复:
6642234 查看本文章