Java:Echo程序(练手)

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终止运行,因此需要进行步骤二的改进:使用多线程来实现。

Alt text

当前Client退出后:

Alt text

步骤二: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();
	}
	
}

Alt text

多个Client同时连接或退出,从Server打印的信息可看到运作正常。


Others 其他

水平所限,或有疏漏,如有任何错误或建议,还望不吝赐教。

转载于:https://my.oschina.net/SCVTheDefect/blog/531161

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值