server端是实现日志功能,使用了多线程原理,可以同时接收多个客户端传过来的数据进行操作,这样同样使用到了beautyeye样式,大家可以去搜索下载。
具体的加载方式这里就不多讲了,如有不明白,可以参照本人的《swing编写client端及多线程server端之client端》,里面有介绍。
本程序界面截图:
布局的话我也不多说了,一个label显示端口,一个文本框输入端口,两个按钮控制运行、停止,一个JTextarea显示客户端传入的信息,一个JScrollPane实现滚动效果;
界面实现可以参照《swing编写client端及多线程server端之client端》里面的介绍。
需要注意的是,JTextArea加到JScrollPane是这样:scroll = new JScrollPane(context);或者scroll = new JScrollPane();scroll.setViewportView(context);都可以实现。
JScrollPane自动滚动效果实现
context.setCaretPosition(context.getDocument().getLength());//JScrollPane自动滚动效果,把光标设置到最后一行
网上还有其他几张方式,用起来不是很好用,有闪屏,这个比较简单推荐给大家
多线程实现代码,网上借鉴的,大家可以参考一下
public void service() { if (serverSocket == null) { try { if (!portText.getText().equals("")) port = Integer.parseInt(portText.getText());//从端口设置文本框得到值,如果没有使用默认值 serverSocket = new ServerSocket(port);//如果端口被占用,会抛出异常 context.append("服务器启动\n");//往JTextArea写数据 } catch (IOException e) { portText.setEditable(true); context.append("服务器关闭,原因:端口已被其他程序占用,请更换!\n");//结尾加'\n'达到换行的效果 } } //线程池 CPU个数*POOL_SIZE executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()* POOL_SIZE); Socket socket = null; while (flag) {//控制开始、停止,flag为全局变量,初始值为false,点击开始时赋值为true try { // 接收客户连接,只要客户进行了连接,就会触发accept();从而建立连接 socket = serverSocket.accept(); executorService.execute(new Handler(socket)); } catch (Exception e) { exceptionHandler();//异常处理 } } } class Handler implements Runnable { private Socket socket; public Handler(Socket socket) { this.socket = socket; } public void run() { try { context.append("New connection accepted " + socket.getRemoteSocketAddress()+"\n"); // 输出流 pw = new PrintWriter(new OutputStreamWriter(socket.getOutputStream(), "UTF-8"), true); // 输入流 br = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8")); String msg = null; while (flag) {//控制开始、停止,flag为全局变量,初始值为false,点击开始时赋值为true if ((msg=br.readLine())!=null) { pw.println("OK");//往客户端发生“OK”,客户端接到之后才会再次发送数据,否者网络阻塞 context.append(socket.getRemoteSocketAddress()+":"+msg+"\n"); context.setCaretPosition(context.getDocument().getLength());//JScrollPane自动滚动效果,把光标设置到最后一行 } } } catch (IOException e) { context.append(socket.getRemoteSocketAddress()+"连接已断开!\n"); } } }