首先启动服务端,客户端通过TCP的三次握手与服务端建立连接;

然后,客户端发送一段字符串,服务端收到字符串后,原封不动的发回给客户端。

ECHO 程序是网络编程通信交互的一个经典案例,称为回应程序,即客户端输入哪些内容,服务端会在这些内容前加上“ECHO”并将信息发回给客户端。

EchoServer.java

  1. import java.io.BufferedReader;
  2. import java.io.BufferedWriter;
  3. import java.io.IOException;
  4. import java.io.InputStream;
  5. import java.io.InputStreamReader;
  6. import java.io.OutputStream;
  7. import java.io.OutputStreamWriter;
  8. import java.net.ServerSocket;
  9. import java.net.Socket;
  10. public class EchoServer {
  11. private ServerSocket server;
  12. public EchoServer() throws IOException {
  13. // 创建服务端套接字对象
  14. this.server = new ServerSocket(8888);
  15. System.out.println("服务器启动" + "在" + 8888 + "端口监听连接请求");
  16. }
  17. // 服务器主要的处理逻辑
  18. public void service() {
  19. // 是否关闭服务端连接
  20. boolean flag = true;
  21. while (flag) {
  22. Socket socket = null;
  23. try {
  24. // 获取连接的客户端套接字对象
  25. socket = server.accept();
  26. // 获取socket相关的输入流和输出流
  27. BufferedReader reader = getReader(socket);
  28. BufferedWriter writer = getWriter(socket);
  29. // 保存客户端发送的数据
  30. String data = null;
  31. // 读取客户端发送的数据
  32. while ((data = reader.readLine()) != null) {
  33. // 当获取的信息是“bye”时,关闭流
  34. if ("bye".equals(data)) {
  35. flag = false;
  36. if (reader != null) {
  37. reader.close();
  38. }
  39. if (writer != null) {
  40. writer.close();
  41. }
  42. break;
  43. } else {
  44. System.out.println("来自客户端的数据:" + data);
  45. // 回显给客户端的数据
  46. writer.write("echo:" + data);
  47. // 插入一个行分割符,readLine()方法用来判定字符串有没结束
  48. writer.newLine();
  49. // 刷新输出缓冲区
  50. writer.flush();
  51. }
  52. }
  53. } catch (IOException e) {
  54. // 设置结束循环
  55. flag = false;
  56. } finally {
  57. try {
  58. if (server != null && (!server.isClosed())) {
  59. server.close();
  60. System.out.println("服务端关闭");
  61. }
  62. } catch (IOException e) {
  63. e.printStackTrace();
  64. }
  65. }
  66. }
  67. }
  68. // 获取socket相关的输入流对象
  69. private BufferedReader getReader(Socket socket) throws IOException {
  70. InputStream in = socket.getInputStream();
  71. return new BufferedReader(new InputStreamReader(in));
  72. }
  73. // 获取socket相关的输出流对象
  74. private BufferedWriter getWriter(Socket socket) throws IOException {
  75. OutputStream out = socket.getOutputStream();
  76. return new BufferedWriter(new OutputStreamWriter(out));
  77. }
  78. public static void main(String arg[]) throws IOException {
  79. new EchoServer().service();
  80. }
  81. }

EchoClient.java

  1. import java.io.BufferedReader;
  2. import java.io.BufferedWriter;
  3. import java.io.IOException;
  4. import java.io.InputStream;
  5. import java.io.InputStreamReader;
  6. import java.io.OutputStream;
  7. import java.io.OutputStreamWriter;
  8. import java.net.Socket;
  9. public class EchoClient {
  10. private Socket socket;
  11. public EchoClient() {
  12. try {
  13. // 创建客户端套接字对象
  14. this.socket = new Socket("127.0.0.1", 8888);
  15. } catch (IOException e) {
  16. e.printStackTrace();
  17. }
  18. }
  19. public void talkToServer() {
  20. System.out.println("请输入要发送给服务端的数据:");
  21. BufferedReader localReader = null;
  22. String data = null;
  23. // 获取客户端套接字相关的输入流和输出流
  24. BufferedReader reader = getReader(socket);
  25. BufferedWriter writer = getWriter(socket);
  26. try {
  27. // 创建读取用户输入的读取流
  28. localReader = new BufferedReader(new InputStreamReader(System.in));
  29. while ((data = localReader.readLine()) != null) {
  30. // 如果客户端输入的数据是"bye",则关闭I/O流
  31. if ("bye".equals(data)) {
  32. System.out.println("客服端关闭!");
  33. if (reader != null) {
  34. reader.close();
  35. }
  36. if (writer != null) {
  37. writer.close();
  38. }
  39. break;
  40. } else {
  41. // readLine方法必须读取到行分割符才返回读取。所以传递给输入流的字符串必须包含行分割符
  42. System.out.println("客户端输出的数据--->\t" + data);
  43. writer.write(data);
  44. // 插入一个行分隔符,作为内容结束的标识
  45. writer.newLine();
  46. // 非常重要的是必须显式的将数据推送到服务器哪里去
  47. writer.flush();
  48. // 读取服务端返回的数据
  49. System.out.println("服务器响应的数据--->\t " + reader.readLine());
  50. }
  51. }
  52. } catch (Exception e) {
  53. e.printStackTrace();
  54. } finally {
  55. // 关闭客户端套接字连接
  56. try {
  57. if (socket != null) {
  58. socket.close();
  59. }
  60. } catch (IOException e) {
  61. e.printStackTrace();
  62. }
  63. }
  64. }
  65. // 获取客户端套接字相关的输出流
  66. private BufferedWriter getWriter(Socket socket) {
  67. try {
  68. OutputStream out = null;
  69. BufferedWriter writer = null;
  70. out = socket.getOutputStream();
  71. writer = new BufferedWriter(new OutputStreamWriter(out));
  72. return writer;
  73. } catch (Exception e) {
  74. e.printStackTrace();
  75. }
  76. return null;
  77. }
  78. // 获取客户端套接字相关的输入流
  79. private BufferedReader getReader(Socket socket) {
  80. try {
  81. InputStream in = null;
  82. BufferedReader reader = null;
  83. in = socket.getInputStream();
  84. reader = new BufferedReader(new InputStreamReader(in));
  85. return reader;
  86. } catch (Exception e) {
  87. e.printStackTrace();
  88. }
  89. return null;
  90. }
  91. public static void main(String[] args) {
  92. new EchoClient().talkToServer();
  93. }
  94. }

编写Java程序,实现一个简单的echo程序(网络编程TCP实践练习)的更多相关文章

  1. UNP学习笔记2——从一个简单的ECHO程序分析TCP客户/服务器之间的通信

    1 概述 编写一个简单的ECHO(回复)程序来分析TCP客户和服务器之间的通信流程,要求如下: 客户从标准输入读入一行文本,并发送给服务器 服务器从网络输入读取这个文本,并回复给客户 客户从网络输入读 ...

  2. 编写一个简单的C++程序

    编写一个简单的C++程序 每个C++程序都包含一个或多个函数(function),其中一个必须命名为main.操作系统通过调用main来运行C++程序.下面是一个非常简单的main函数,它什么也不干, ...

  3. 用C语言编写一个简单的词法分析程序

    问题描述: 用C或C++语言编写一个简单的词法分析程序,扫描C语言小子集的源程序,根据给定的词法规则,识别单词,填写相应的表.如果产生词法错误,则显示错误信息.位置,并试图从错误中恢复.简单的恢复方法 ...

  4. 利用JSP编程技术实现一个简单的购物车程序

    实验二   JSP编程 一.实验目的1. 掌握JSP指令的使用方法:2. 掌握JSP动作的使用方法:3. 掌握JSP内置对象的使用方法:4. 掌握JavaBean的编程技术及使用方法:5. 掌握JSP ...

  5. JAVA课程设计——一个简单的教务人事管理系统

    大三上学期期末总结,没错,上学期,写在下学期新学期开始,哈哈哈. 上学期学习了面向对象程序设计,课程设计的题目使用JAVA语言完成一个简单的教务人事管理系统,能够实现访问数据库的登录验证,分别按部门和 ...

  6. netty入门实现简单的echo程序

    最近看以往在程序中编写的代码,发现有一个功能是使用socket通讯来实现的,而那个时候使用的是基于bio的阻塞io来实现的,最近在看netty,发现可以使用netty来使用nio的方式来实现,此博客记 ...

  7. 如何创建一个简单的struts2程序

    如何创建一个简单的Struts2程序 “计应134(实验班) 凌豪” 1.创建一个新的Web项目test(File->new->Web Project) 2.Struts2框架的核心配置文 ...

  8. Linux系统学习笔记之 1 一个简单的shell程序

    不看笔记,长时间不用自己都忘了,还是得经常看看笔记啊. 一个简单的shell程序 shell结构 1.#!指定执行脚本的shell 2.#注释行 3.命令和控制结构 创建shell程序的步骤 第一步: ...

  9. 第一讲 一个简单的Qt程序分析

    本文概要:通过一个简单的Qt程序来介绍Qt程序编写的基本框架与一些Qt程序中常见的概念 #include <QApplication> #include <QPushButton&g ...

随机推荐

  1. Swift3.0 延时执行

    //延时1s执行 DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + Double(Int64(1*NSEC_PER_SEC))/ ...

  2. zabbix之模板制作(memcache redis)

    #:找一台主机安装redis和memcached(记得安装zabbix-agent) root@ubuntu:~# apt install redis root@ubuntu:~# apt insta ...

  3. Spring Boot下使用JSP页面

    一.创建webapp目录 在src/main下创建webapp目录,用于存放jsp文件.这就是一个普通的目录,无需执行Mark Directory As 二.创建jsp 1.指定web资源目录 在sp ...

  4. java通过反射获取Java对象属性值

    说明: 作为反射工具类,通过对象和属性的名字获取对象属性的值,如果在当前对象属性没有找到,依次向上收集所有父类的属 性,直到找到属性值,没有找到返回null: 代码: 1.classUtil pack ...

  5. spring boot springMVC扩展配置 。WebMvcConfigurer ,WebMvcConfigurerAdapter

    摘要: 在spring boot中 MVC这部分也有默认自动配置,也就是说我们不用做任何配置,那么也是OK的,这个配置类就是 WebMvcAutoConfiguration,但是也时候我们想设置自己的 ...

  6. [MySQL实战-Mysql基础篇]-mysql的日志

    参考文章: https://www.cnblogs.com/f-ck-need-u/archive/2018/05/08/9010872.html https://dev.mysql.com/doc/ ...

  7. 测试工具_http_load

    目录 一.简介 二.例子 三.参数 一.简介 http_load以并行复用的方式运行,用以测试Web服务器的吞吐量与负载.但是它不同于大多数压力测试工具,其可以以一个单一的进程运行,这样就不会把客户机 ...

  8. vue在某页面监听键盘输入事件

    需求:在某一网页,通过上下左右键控制一些操作 实现: 1.基本代码: 因为没有绑定特定的元素.所以我们将事件绑定到document上. //当前页面监视键盘输入 document.onkeydown ...

  9. java 常用类库:Object类和Objects类

    1,Object类: Object类是所有的类,数组,枚举的父类,也就是说,JAVA中允许把任何的对象赋值给Object类(包括基础数据类型),当定义一个类的时候,没有使用extends关键字显示指定 ...

  10. 在执行java代码时,设置了断点,然后莫名的没执行完方法内的代码就结束了,此刻一般在出错处代码用try,catch包括起来

    在执行java代码时,设置了断点,然后莫名的没执行完方法内的代码就结束了,此刻一般在出错处代码用try,catch包括起来就能看到是什么异常了,记住try,catch语句的作用