Java:Echo程序(练手)
2015-11-17 00:00
639 查看
摘要: 涉及到I/O、TCP Socket、多线程等内容的小程序,非常适合用来练手。
涉及:
I/O
Socket
Multi-Thread
注意(坑):
网络IO中只能传输字节流,不能直接传输字符流。
无论是Client还是Server,都应该将获取的字节流内容转换为字符流,以防中文乱码。
Client可以反复向Server发送信息;
Server:
Client:
虽然实现了基本功能,但却只能处理单个Client连接。
如图:左上角为Server,只能显示单个Client的消息(右上角),不能处理其他Client的连接(左下角),并且会在当前Client(右上角)退出后抛出
当前Client退出后:
Server里将循环中的代码用
Client不变:
多个Client同时连接或退出,从Server打印的信息可看到运作正常。
Abstract 概述
Echo程序,即在Client输入内容,Server接收到后在开头加上“Echo: ”后再返回给Client的程序。这是一个TCP连接的程序。涉及:
I/O
Socket
Multi-Thread
注意(坑):
网络IO中只能传输字节流,不能直接传输字符流。
无论是Client还是Server,都应该将获取的字节流内容转换为字符流,以防中文乱码。
Description 具体步骤
步骤一:实现基本功能
Server可以反复接收由Client发送的消息并回应;Client可以反复向Server发送信息;
Server:
public class EchoServer { @SuppressWarnings("resource") public static void main(String[] args) throws IOException { ServerSocket server = null; Socket client = null; PrintStream out = null; BufferedReader in = null; System.out.println("Running service..."); //service start server = new ServerSocket(8888); System.out.println("Waiting for connection.."); while(true){ client = server.accept(); SocketAddress addr = client.getRemoteSocketAddress(); System.out.println("Establishing connection: " + addr); //keep talking with the user while(true){ in = new BufferedReader(new InputStreamReader(client.getInputStream())); String content = in.readLine(); //if user wanna quit the program, just let him go. if(content == null || ".quit".equals(content.toLowerCase())) break; System.out.println("Receive: " + content); out = new PrintStream(client.getOutputStream()); out.println("ECHO: " + content); System.out.println("Replied."); } in.close(); out.close(); client.close(); System.out.println("Session ended: " + addr); } } }
Client:
public class EchoClient { public static void main(String[] args) throws IOException { BufferedReader kbInput = null; Socket socket = null; PrintStream out = null; BufferedReader in = null; socket = new Socket("localhost", 8888); kbInput = new BufferedReader(new InputStreamReader(System.in)); while(true){ //get keyboard input String content = kbInput.readLine(); if(content == null || content.trim().length() == 0 || ".quit".equals(content)) break; //send message to server out = new PrintStream(socket.getOutputStream()); out.println(content); //retrieve message from server in = new BufferedReader(new InputStreamReader(socket.getInputStream())); String reply = in.readLine(); System.out.println(reply); } socket.close(); } }
虽然实现了基本功能,但却只能处理单个Client连接。
如图:左上角为Server,只能显示单个Client的消息(右上角),不能处理其他Client的连接(左下角),并且会在当前Client(右上角)退出后抛出
SocketException,Server终止运行,因此需要进行步骤二的改进:使用多线程来实现。
当前Client退出后:
步骤二:Server改用多线程
新建线程类处理Client的输入:public class EchoServerThread implements Runnable{ private Socket socket; public EchoServerThread(Socket socket) { this.socket = socket; } @Override public void run(){ BufferedReader reader = null; PrintStream out = null; try{ SocketAddress addr = socket.getRemoteSocketAddress(); System.out.println("Connected: " + addr); reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); out = new PrintStream(socket.getOutputStream()); while(true){ String content = reader.readLine(); //if user wanna leave, just let him go if(content == null || content.trim().length() == 0 || ".quit".equals(content)) break; out.println("Echo: " + content); System.out.println("Received: " + content); } socket.close(); System.out.println("Connection ended: " + addr); }catch(IOException e){ e.printStackTrace(); } } }
Server里将循环中的代码用
EchoServerThread替换掉:
public class EchoServer { @SuppressWarnings("resource") public static void main(String[] args) throws IOException { ServerSocket server = null; Socket client = null; PrintStream out = null; BufferedReader in = null; System.out.println("Running service..."); //service start server = new ServerSocket(8888); System.out.println("Waiting for connection.."); while(true){ client = server.accept(); new Thread(new EchoServerThread(client)).start(); } } }
Client不变:
public class EchoClient { public static void main(String[] args) throws IOException { BufferedReader kbInput = null; Socket socket = null; PrintStream out = null; BufferedReader in = null; socket = new Socket("localhost", 8888); kbInput = new BufferedReader(new InputStreamReader(System.in)); while(true){ //get keyboard input String content = kbInput.readLine(); if(content == null || content.trim().length() == 0 || ".quit".equals(content)) break; //send message to server out = new PrintStream(socket.getOutputStream()); out.println(content); //retrieve message from server in = new BufferedReader(new InputStreamReader(socket.getInputStream())); String reply = in.readLine(); System.out.println(reply); } socket.close(); } }
多个Client同时连接或退出,从Server打印的信息可看到运作正常。
Others 其他
水平所限,或有疏漏,如有任何错误或建议,还望不吝赐教。相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树
- [原创]java局域网聊天系统