编写Java程序,实现一个简单的echo程序(网络编程TCP实践练习)
首先启动服务端,客户端通过TCP的三次握手与服务端建立连接;
然后,客户端发送一段字符串,服务端收到字符串后,原封不动的发回给客户端。
ECHO 程序是网络编程通信交互的一个经典案例,称为回应程序,即客户端输入哪些内容,服务端会在这些内容前加上“ECHO”并将信息发回给客户端。


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();
}
}
编写Java程序,实现一个简单的echo程序(网络编程TCP实践练习)的更多相关文章
- UNP学习笔记2——从一个简单的ECHO程序分析TCP客户/服务器之间的通信
1 概述 编写一个简单的ECHO(回复)程序来分析TCP客户和服务器之间的通信流程,要求如下: 客户从标准输入读入一行文本,并发送给服务器 服务器从网络输入读取这个文本,并回复给客户 客户从网络输入读 ...
- 编写一个简单的C++程序
编写一个简单的C++程序 每个C++程序都包含一个或多个函数(function),其中一个必须命名为main.操作系统通过调用main来运行C++程序.下面是一个非常简单的main函数,它什么也不干, ...
- 用C语言编写一个简单的词法分析程序
问题描述: 用C或C++语言编写一个简单的词法分析程序,扫描C语言小子集的源程序,根据给定的词法规则,识别单词,填写相应的表.如果产生词法错误,则显示错误信息.位置,并试图从错误中恢复.简单的恢复方法 ...
- 利用JSP编程技术实现一个简单的购物车程序
实验二 JSP编程 一.实验目的1. 掌握JSP指令的使用方法:2. 掌握JSP动作的使用方法:3. 掌握JSP内置对象的使用方法:4. 掌握JavaBean的编程技术及使用方法:5. 掌握JSP ...
- JAVA课程设计——一个简单的教务人事管理系统
大三上学期期末总结,没错,上学期,写在下学期新学期开始,哈哈哈. 上学期学习了面向对象程序设计,课程设计的题目使用JAVA语言完成一个简单的教务人事管理系统,能够实现访问数据库的登录验证,分别按部门和 ...
- netty入门实现简单的echo程序
最近看以往在程序中编写的代码,发现有一个功能是使用socket通讯来实现的,而那个时候使用的是基于bio的阻塞io来实现的,最近在看netty,发现可以使用netty来使用nio的方式来实现,此博客记 ...
- 如何创建一个简单的struts2程序
如何创建一个简单的Struts2程序 “计应134(实验班) 凌豪” 1.创建一个新的Web项目test(File->new->Web Project) 2.Struts2框架的核心配置文 ...
- Linux系统学习笔记之 1 一个简单的shell程序
不看笔记,长时间不用自己都忘了,还是得经常看看笔记啊. 一个简单的shell程序 shell结构 1.#!指定执行脚本的shell 2.#注释行 3.命令和控制结构 创建shell程序的步骤 第一步: ...
- 第一讲 一个简单的Qt程序分析
本文概要:通过一个简单的Qt程序来介绍Qt程序编写的基本框架与一些Qt程序中常见的概念 #include <QApplication> #include <QPushButton&g ...
随机推荐
- C++字节对齐(对象大小)
内部数据成员对齐参考这篇 https://www.cnblogs.com/area-h-p/p/10316128.html 这里只强调C++字节对齐特点 ①静态数据成员属于类域,在对象中不占大小 ②若 ...
- 【STM32】使用SDIO进行SD卡读写,包含文件管理FatFs(八)-认识内存管理
[STM32]使用SDIO进行SD卡读写,包含文件管理FatFs(一)-初步认识SD卡 [STM32]使用SDIO进行SD卡读写,包含文件管理FatFs(二)-了解SD总线,命令的相关介绍 [STM3 ...
- @Transactional注解详细使用
一.@Transactional 注解使用 @Transactional 注解只能用在public 方法上,如果用在protected或者private的方法上,不会报错,但是该注解不会生效. @T ...
- 基于docker 操作mysql5.7
1. 安装好 docker 2. 拉取 mysql5.7 镜像: docker pull mysql:5.7 其他版本 mysql:https://hub.docker.com/_/mysql?tab ...
- 【Java 8】函数式接口(二)—— 四大函数接口介绍
前言 Java8中函数接口有很多,大概有几十个吧,具体究竟是多少我也数不清,所以一开始看的时候感觉一脸懵逼,不过其实根本没那么复杂,毕竟不应该也没必要把一个东西设计的很复杂. 几个单词 在学习了解之前 ...
- python实现skywalking邮件告警webhook接口
1.介绍 Skywalking可以对链路追踪到数据进行告警规则配置,例如响应时间.响应百分比等.发送警告通过调用webhook接口完成.webhook接口用户可以自定义. 2.默认告警规则 告警配置文 ...
- shell脚本 mysqldump方式全备份mysql
一.简介 源码地址 日期:2018/10/8 介绍:mysqldump方式全备份脚本,并保存固定天数的全备份 效果图: 二.使用 适用:centos6+ 语言:中文 注意:使用前先查看脚本,修改对应变 ...
- Jenkins获取jar包的快照号
目录 一.简介 二.脚本 一.简介 主要用于打jar包的工程,显示快照包的名字.当jar打包完成后,会在target目录中,截取快照名. 二.脚本 1.脚本return-version.sh #!/b ...
- proxy跨域
跨域 浏览器访问非同源的网址时,会被限制访问,出现跨域问题. 解决方案: 1.response 添加 header(CORS) 2.JSONP 方式 3.全局对象+iframe (1)document ...
- ciscn_2019_s_3
拿到题目例行检查 64位程序开启了nx保护,将程序放入ida 看到没有system函数第一时间想到的就是泄露libc来做,后来才知道是我学识尚浅,需要用execve函数来做 进入main发现跳转到vu ...