您的位置:首页 > 编程语言 > Java开发

Java:Echo程序(练手)

2015-11-17 00:00 639 查看
摘要: 涉及到I/O、TCP Socket、多线程等内容的小程序,非常适合用来练手。

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