网络编程-Echo程序进化


场景描述:Echo程序是一个网络编程通信交互的一个经典案例,称为“回应程序”。即客户端输入什么内容,服务端就会在这些内容前加上“Echo”\,并将信息发回给客户端。





第一个TCP程序:

建立服务器程序HelloServer.java
import java.net.* ;
import java.io.* ;
public class HelloServer{
	public static void main(String args[]) throws Exception {	// 所有异常抛出
		ServerSocket server = null ;		// 定义ServerSocket类
		Socket client = null ;	// 表示客 户端
		PrintStream out = null ;		// 打印流输出最方便
		server = new ServerSocket(8888) ;	// 服务器在8888端口上监听
		System.out.println("服务器运行,等待客户端连接。") ;
		client = server.accept() ;		// 得到连接,程序进入到阻塞状态
		String str = "hello world" ;	// 表示要输出的信息
		out = new PrintStream(client.getOutputStream()) ;
		out.println(str) ;	// 向客户端输出信息
		client.close() ;
		server.close() ;
	}
};
程序运行结果:
服务器运行,等待客户端连接。
PS:服务器端建立完成后,因为其是以TCP为通信协议的,可以使用tenet命令进行验证,输入“open loaclhost 8888”,即可取得服务器的输出信息。


编写客户端程序HelloCilent.java
import java.net.* ;
import java.io.* ;
public class HelloClient{
	public static void main(String args[]) throws Exception {	// 所有异常抛出
		Socket client = null ;	// 表示客 户端
		client = new Socket("localhost",8888) ;
		BufferedReader buf = null ;	// 一次性接收完成
		buf = new BufferedReader(new InputStreamReader(client.getInputStream())) ;
		String str = buf.readLine() ;
		System.out.println("服务器端输出内容:" + str) ;
		buf.close() ;
		client.close() ;
	}
};
程序运行结果(重新打开一个命令行窗口):
服务器端输出内容:hello world



Echo程序:

回看之前的Hello程序,服务器每次执行完都会退出,这是因为服务器只能接收一个客户端的连接,主要是由于accept()方法只能使用一次。那么现在让我们循环使用accept()吧!
服务器端EchoServer.java
import java.net.* ;
import java.io.* ;
public class EchoServer{
	public static void main(String args[]) throws Exception {	// 所有异常抛出
		ServerSocket server = null ;		// 定义ServerSocket类
		Socket client = null ;	// 表示客 户端
		BufferedReader buf = null ;	// 接收输入流
		PrintStream out = null ;		// 打印流输出最方便
		server = new ServerSocket(8888) ;	// 服务器在8888端口上监听
		boolean f = true ;	// 定义个标记位
		while(f){
			System.out.println("服务器运行,等待客户端连接。") ;
			client = server.accept() ;		// 得到连接,程序进入到阻塞状态
			out = new PrintStream(client.getOutputStream()) ;
			// 准备接收客户端的输入信息
			buf = new BufferedReader(new InputStreamReader(client.getInputStream())) ;
			boolean flag = true ;	// 标志位,表示可以一直接收并回应信息
			while(flag){
				String str = buf.readLine() ;		// 接收客户端发送的内容
				if(str==null||"".equals(str)){	// 表示没有内容
					flag = false ;	// 退出循环
				}else{
					if("bye".equals(str)){	// 如果输入的内容为bye表示结束
						flag = false ;
					}else{
						out.println("ECHO : " + str) ;	// 回应信息
					}
				}
			}
			client.close() ;
		}
		server.close() ;
	}
};


客户端端Echo.java
import java.net.* ;
import java.io.* ;
public class EchoClient{
	public static void main(String args[]) throws Exception {	// 所有异常抛出
		Socket client = null ;	// 表示客户端
		client = new Socket("localhost",8888) ;	// 指定连接主机及端口
		BufferedReader buf = null ;	// 一次性接收完成
		PrintStream out = null ;	// 向服务器端发送数据
		BufferedReader input = null ;	
		
		input = new BufferedReader(
			new InputStreamReader(System.in)) ;	// 接收键盘数据
		buf = new BufferedReader(
				new InputStreamReader(
					client.getInputStream())) ;	// 接收服务器端输入信息
		out = new PrintStream(client.getOutputStream()) ;
		boolean flag = true ;		// 定义标志位

		while(flag){					// 不断发送和接收数据
			System.out.print("输入信息:") ;
			String str = input.readLine() ;	// 接收键盘的输入信息
			out.println(str) ;
			if("bye".equals(str)){		// 如果输入bye表示结束
				flag = false ;
			}else{
				String echo = buf.readLine() ;	// 接收返回结果
				System.out.println(echo) ;	// 输出回应Echo信息
			}
		}
		buf.close() ;				// 关闭Socket
		client.close() ;			// 关闭输入流
	}
};



严重问题:即现在服务器端每次只能有一个用户连接,属于单线程的处理机制。

进化:在服务器上应用多线程。

在每一个用户连接之后启动一个新的线程:EchoThread.java
import java.net.* ;
import java.io.* ;
public class EchoThread implements Runnable{
	private Socket client = null ;
	public EchoThread(Socket client){
		this.client = client ;
	}
	public void run(){
		BufferedReader buf = null ;	// 接收输入流
		PrintStream out = null ;		// 打印流输出最方便
		try{
			out = new PrintStream(client.getOutputStream()) ;
			// 准备接收客户端的输入信息
			buf = new BufferedReader(new InputStreamReader(client.getInputStream())) ;
			boolean flag = true ;	// 标志位,表示可以一直接收并回应信息
			while(flag){
				String str = buf.readLine() ;		// 接收客户端发送的内容
				if(str==null||"".equals(str)){	// 表示没有内容
					flag = false ;	// 退出循环
				}else{
					if("bye".equals(str)){	// 如果输入的内容为bye表示结束
						flag = false ;
					}else{
						out.println("ECHO : " + str) ;	// 回应信息
					}
				}
			}
			client.close() ;
		}catch(Exception e){}
		
	}
};

编写EchoThreadServer类,并使用以上的EchoThread类:EchoThreadServer.java
import java.net.* ;
import java.io.* ;
public class EchoThreadServer{
	public static void main(String args[]) throws Exception {	// 所有异常抛出
		ServerSocket server = null ;		// 定义ServerSocket类
		Socket client = null ;	// 表示客 户端
		server = new ServerSocket(8888) ;	// 服务器在8888端口上监听
		boolean f = true ;	// 定义个标记位
		while(f){
			System.out.println("服务器运行,等待客户端连接。") ;
			client = server.accept() ;		// 得到连接,程序进入到阻塞状态
			new Thread(new EchoThread(client)).start() ;	// 每一个客户端表示一个线程
		}
		server.close() ;
	}
};


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值