编写Java程序,实现一个简单的echo程序(网络编程TCP实践练习)

简介: 编写Java程序,实现一个简单的echo程序(网络编程TCP实践练习)

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


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


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

45.png46.png


EchoServer.java

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class EchoServer {
  private ServerSocket server;
  public EchoServer() throws IOException {
    // 创建服务端套接字对象
    this.server = new ServerSocket(8888);
    System.out.println("服务器启动" + "在" + 8888 + "端口监听连接请求");
  }
  // 服务器主要的处理逻辑
  public void service() {
    // 是否关闭服务端连接
    boolean flag = true;
    while (flag) {
      Socket socket = null;
      try {
        // 获取连接的客户端套接字对象
        socket = server.accept();
        // 获取socket相关的输入流和输出流
        BufferedReader reader = getReader(socket);
        BufferedWriter writer = getWriter(socket);
        // 保存客户端发送的数据
        String data = null;
        // 读取客户端发送的数据
        while ((data = reader.readLine()) != null) {
          // 当获取的信息是“bye”时,关闭流
          if ("bye".equals(data)) {
            flag = false;
            if (reader != null) {
              reader.close();
            }
            if (writer != null) {
              writer.close();
            }
            break;
          } else {
            System.out.println("来自客户端的数据:" + data);
            // 回显给客户端的数据
            writer.write("echo:" + data);
            // 插入一个行分割符,readLine()方法用来判定字符串有没结束
            writer.newLine();
            // 刷新输出缓冲区
            writer.flush();
          }
        }
      } catch (IOException e) {
        // 设置结束循环
        flag = false;
      } finally {
        try {
          if (server != null && (!server.isClosed())) {
            server.close();
            System.out.println("服务端关闭");
          }
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }
  }
  // 获取socket相关的输入流对象
  private BufferedReader getReader(Socket socket) throws IOException {
    InputStream in = socket.getInputStream();
    return new BufferedReader(new InputStreamReader(in));
  }
  // 获取socket相关的输出流对象
  private BufferedWriter getWriter(Socket socket) throws IOException {
    OutputStream out = socket.getOutputStream();
    return new BufferedWriter(new OutputStreamWriter(out));
  }
  public static void main(String arg[]) throws IOException {
    new EchoServer().service();
  }
}


EchoClient.java


import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
public class EchoClient {
  private Socket socket;
  public EchoClient() {
    try {
      // 创建客户端套接字对象
      this.socket = new Socket("127.0.0.1", 8888);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
  public void talkToServer() {
    System.out.println("请输入要发送给服务端的数据:");
    BufferedReader localReader = null;
    String data = null;
    // 获取客户端套接字相关的输入流和输出流
    BufferedReader reader = getReader(socket);
    BufferedWriter writer = getWriter(socket);
    try {
      // 创建读取用户输入的读取流
      localReader = new BufferedReader(new InputStreamReader(System.in));
      while ((data = localReader.readLine()) != null) {
        // 如果客户端输入的数据是"bye",则关闭I/O流
        if ("bye".equals(data)) {
          System.out.println("客服端关闭!");
          if (reader != null) {
            reader.close();
          }
          if (writer != null) {
            writer.close();
          }
          break;
        } else {
          // readLine方法必须读取到行分割符才返回读取。所以传递给输入流的字符串必须包含行分割符
          System.out.println("客户端输出的数据--->\t" + data);
          writer.write(data);
          // 插入一个行分隔符,作为内容结束的标识
          writer.newLine();
          // 非常重要的是必须显式的将数据推送到服务器哪里去
          writer.flush();
          // 读取服务端返回的数据
          System.out.println("服务器响应的数据--->\t " + reader.readLine());
        }
      }
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      // 关闭客户端套接字连接
      try {
        if (socket != null) {
          socket.close();
        }
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }
  // 获取客户端套接字相关的输出流
  private BufferedWriter getWriter(Socket socket) {
    try {
      OutputStream out = null;
      BufferedWriter writer = null;
      out = socket.getOutputStream();
      writer = new BufferedWriter(new OutputStreamWriter(out));
      return writer;
    } catch (Exception e) {
      e.printStackTrace();
    }
    return null;
  }
  // 获取客户端套接字相关的输入流
  private BufferedReader getReader(Socket socket) {
    try {
      InputStream in = null;
      BufferedReader reader = null;
      in = socket.getInputStream();
      reader = new BufferedReader(new InputStreamReader(in));
      return reader;
    } catch (Exception e) {
      e.printStackTrace();
    }
    return null;
  }
  public static void main(String[] args) {
    new EchoClient().talkToServer();
  }
}
相关文章
|
1天前
|
小程序 前端开发 Java
Java程序的种类和结构
Java程序的种类和结构
|
2天前
|
消息中间件 Java Linux
2024年最全BATJ真题突击:Java基础+JVM+分布式高并发+网络编程+Linux(1),2024年最新意外的惊喜
2024年最全BATJ真题突击:Java基础+JVM+分布式高并发+网络编程+Linux(1),2024年最新意外的惊喜
|
2天前
|
缓存 算法 Java
如何提高Java程序的性能?
Java是一种非常流行的编程语言,但是在处理大规模数据和高并发时,程序性能容易受到影响。本文将分享一些提高Java程序性能的技巧。
|
6天前
|
算法 Java Python
保姆级Java入门练习教程,附代码讲解,小白零基础入门必备
保姆级Java入门练习教程,附代码讲解,小白零基础入门必备
|
7天前
|
搜索推荐 算法 Java
滚雪球学Java(29):数组长度和排序算法:让你的程序更高效
【5月更文挑战第4天】🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
15 0
滚雪球学Java(29):数组长度和排序算法:让你的程序更高效
|
7天前
|
Java 开发者 Spring
Java一分钟之-Java网络编程基础:Socket通信
【5月更文挑战第13天】本文介绍了Java Socket编程基础知识,包括使用`ServerSocket`和`Socket`类建立连接,通过`OutputStream`和`InputStream`进行数据传输。常见问题涉及忘记关闭Socket导致的资源泄漏、网络异常处理及并发同步。理解Socket通信原理并掌握异常处理、资源管理和并发控制,能帮助开发者构建更稳定的网络应用。
31 1
|
7天前
|
前端开发 Java 应用服务中间件
【异常解决】java程序连接MinIO报错The request signature we calculated does not match the signature you provided.
【异常解决】java程序连接MinIO报错The request signature we calculated does not match the signature you provided.
27 0
|
7天前
|
网络协议 算法 Java
|
7天前
|
网络协议 算法 Java
【Java网络编程】网络编程概述、UDP通信(DatagramPacket 与 DatagramSocket)
【Java网络编程】网络编程概述、UDP通信(DatagramPacket 与 DatagramSocket)
22 3
|
7天前
|
网络协议 Dubbo Java
【网络编程】理解客户端和服务器并使用Java提供的api实现回显服务器
【网络编程】理解客户端和服务器并使用Java提供的api实现回显服务器
11 0