JAVA Socket模拟简单的通讯(代码实例),javasocket
分享于 点击 20094 次 点评:169
JAVA Socket模拟简单的通讯(代码实例),javasocket
依旧使用bio流。
使用线程池技术,管理服务器线程。
实现服务器关机处理,解决大部分异常处理。
package xin.tomdonkey.net.bio; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; public class Server { /** * 循环标记,是否执行接受新连接的标记 * 仅标记是否接受新连接,不标记其他状态 */ private int port; private boolean life; private ServerSocket serverSocket ; private ExecutorService threadPool = Executors.newCachedThreadPool(); public void startup() { while (life) { try { Socket socket = serverSocket.accept(); threadPool.submit(new ServerClient(socket)); System.out.println("一个新任务进入线程池"); System.out.println("当前线程池为:" + threadPool); } catch (IOException e) { System.err.println("serverSocket被关闭了,主循环解除阻塞"); } } } public void shutDown() { life = false; System.err.println("主循环退出"); try { serverSocket.close(); } catch (IOException e) { e.printStackTrace(); } shutdownAndAwaitTermination(threadPool); System.err.println("系统正常退出"); } /** * 此方法一定无法终止此程序下正在运行的线程, * 此方法只能让能响应interrupt的线程终止 * 而此程序下使用的是bio,并不会抛出interrupt * 故而只会等待线程10s执行时间,为执行完成,直接终止程序。 * @param pool */ private void shutdownAndAwaitTermination(ExecutorService pool) { pool.shutdown(); try { if (!pool.awaitTermination(5, TimeUnit.SECONDS)) { pool.shutdownNow(); if (!pool.awaitTermination(5, TimeUnit.SECONDS)) { System.err.println("线程池中存在无法被关闭的线程..."); System.err.println("系统强制关闭..."); System.exit(-1); } } } catch (InterruptedException ie) { pool.shutdownNow(); Thread.currentThread().interrupt(); } } /** * 采用默认端口6655创建服务器 * * @throws IOException */ public Server() throws IOException { this(6655); } /** * 指定端口port创建服务器 * * @param port 服务器监听的端口 * @throws IOException */ public Server(int port) throws IOException { this.port = port; this.life = true; this.serverSocket = new ServerSocket(port); } public static void main(String[] args) throws IOException { Server server = new Server(); new Thread(()->{ try { Thread.sleep(20000); } catch (InterruptedException e) { e.printStackTrace(); } server.shutDown(); }).start(); server.startup(); } }
package xin.tomdonkey.net.bio; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.util.Random; public class ServerClient implements Runnable { private boolean flag; private InputStream inputStream ; private OutputStream outputStream ; public ServerClient(Socket socket) { flag = true; try { this.inputStream = socket.getInputStream(); this.outputStream = socket.getOutputStream(); } catch (IOException e) { flag = false; System.err.println("服务器获取输入输出流时,socket出现异常,run方法将执行空语句,直接退出线程"); } } @Override public void run() { while (flag) { try { //线程启动,即阻塞,直到客户端发出数据 //可以做一个优化,收不到数据即销毁当前线程以及链接和流 int r= inputStream.read(); System.out.println("服务器收到:" + r); //收到后即回复给客户端一个随机值 byte b = (byte)new Random().nextInt(100); outputStream.write(b); System.out.println("服务器写出:" + b); System.out.println("完成一次回复\n"); } catch (IOException e) { //客户端掉线了,或者IO出现问题抛出此异常,让此线程运行终止 System.out.println("由于客户端发生异常,关闭此服务线程"); flag = false; } } } }
package xin.tomdonkey.net.bio; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.util.Random; public class Client { Socket socket ; boolean flag = false; InputStream inputStream ; OutputStream outputStream ; public Client(String address,int port) throws IOException { this.socket = new Socket(address,port); this.inputStream = socket.getInputStream(); this.outputStream = socket.getOutputStream(); } public void startup() throws IOException, InterruptedException { flag = true; while (flag) { //由客户端发起,向服务器写出数据,一个随机byte值 byte b = (byte)new Random().nextInt(100); outputStream.write(b); System.out.println("写出:" + b); //写出完成之后,线程阻塞,直到收到服务器发来的值为止 int r = inputStream.read(); System.out.println("收到:" + r); System.out.println("完成一次请求\n"); //收到之后线程休眠2s,再向服务器写出数据 Thread.sleep(2000); } } public static void main(String[] args) throws IOException, InterruptedException { Client client = new Client("127.0.0.1",6655); client.startup(); } }
用户点评