当前位置:网站首页>Socket类关于TCP字符流编程的理解学习
Socket类关于TCP字符流编程的理解学习
2022-07-28 12:44:00 【爱学习的大雄】
基本介绍
套接字(socket):是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。它是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信息:连接使用的协议,本地主机的IP地址,本地进程的协议端口,远地主机的IP地址,远地进程的协议端口
- socket是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。
- socket简单的说,由 端口,协议,地址三个组成部分。
- 套接字之间的连接过程分为三个步骤:服务器监听,客户端请求,连接确认。
- 由于通常情况下Socket连接就是TCP连接,因此Socket连接一旦建立,通信双方即可开始相互发送数据内容,直到双方连接断开。
- 但在实际网络应用中,客户端到服务器之间的通信往往需要穿越多个中间节点,例如路由器、网关、防火墙等,大部分防火墙默认会关闭长时间处于非活跃状态的连接而导致Socket 连接断连,因此需要通过轮询告诉网络,该连接处于活跃状态。
Socket主要用于开发网络应用程序,其背广泛采用
通信的两端都需要有Socket,是两台机器间通信的断点
网络通信其实就是Socket的通信
Socket允许程序把网络连接当成一个流,数据在两个Socket间通过IO传输
一般主动发起通信的应用程序属于客户端,等待通信请求的为服务端
示意图:

代码实现
一定要注意,必须要先开启服务端,在启动客户端,否则会报错
**注意:**这里的代码示例都是关于发送与接收信息,如果需要发送或接收图片等都差不多,只是必须要使用字节流而不能使用字符流,基本流程都是使用IO中的知识。
需求1:
- 编写一个服务端和一个客户端
- 服务端在9999端口监听
- 客户端连接到服务器,发送"hello,server",退出
- 服务端接收到客户端发送的信息并输出,退出
服务端
/** * * 服务端 * 需求:接收从客户端发来的信息并输出 * * @author:雷子杰 * @date:2022/7/27 */
public class ScoketTCP01Server {
public static void main(String[] args) throws IOException {
//新建serverSocket对象,实现9999端口监听
ServerSocket serverSocket = new ServerSocket(9999);
//客户端连接后会生成管道
Socket socket = serverSocket.accept();
//获取管道的输入流
InputStream inputStream = socket.getInputStream();
byte[] buf=new byte[1024];
int len = 0;
while ((len = inputStream.read(buf))!=-1){
System.out.println(new String(buf,0,len));
}
//关闭流
inputStream.close();
socket.close();
serverSocket.close();
}
}
客户端
输出流写入数据后一定要进行flush(),同时进行结束标记
/** * * 客户端 * 需求:向服务器端发送一条信息 * * @author:雷子杰 * @date:2022/7/27 */
public class ScoketTCP01Client {
public static void main(String[] args) throws IOException {
//获取socket连接
Socket socket = new Socket(InetAddress.getLocalHost(),9999);
//获取输出流对象
OutputStream outputStream = socket.getOutputStream();
//往输出流中写入信息
outputStream.write("hello,server".getBytes());
//关闭流
outputStream.close();
socket.close();
}
}
测试结果
服务端收到信息

需求2
- 编写一个服务端和一个客户端
- 服务端在9999端口监听
- 客户端连接到服务器,发送"hello,server",并接收服务端回发的"hello,client",退出
- 服务端接收到客户端发送的信息输出,并发送"hello,client",退出
服务端
输出流写入数据后一定要进行flush(),同时进行结束标记
/** * * 服务端 * 需求:接收从客户端发来的信息输出,并返回一条消息给客户端 * * * @author:雷子杰 * @date:2022/7/27 */
public class ScoketTCP02Server {
public static void main(String[] args) throws IOException {
//新建serverSocket对象,实现9999端口监听
ServerSocket serverSocket = new ServerSocket(9999);
//客户端连接后会生成管道
Socket socket = serverSocket.accept();
//获取管道的输入流,获取客户端发来的信息
InputStream inputStream = socket.getInputStream();
byte[] buf=new byte[1024];
int len = 0;
while ((len = inputStream.read(buf))!=-1){
System.out.println(new String(buf,0,len));
}
//关闭读取
socket.shutdownInput();
//获取输出流对象
OutputStream outputStream = socket.getOutputStream();
//往输出流中写入信息,发送给服务端
outputStream.write("hello,client".getBytes());
//关闭写入
socket.shutdownOutput();
//关闭流
outputStream.close();
inputStream.close();
socket.close();
serverSocket.close();
}
}
客户端
输出流写入数据后一定要进行flush(),同时进行结束标记
/** * * 客户端 * 需求:向服务器端发送一条信息,并接收从服务器端返回的一条信息 * * @author:雷子杰 * @date:2022/7/27 */
public class ScoketTCP02Client {
public static void main(String[] args) throws IOException {
//获取socket连接
Socket socket = new Socket(InetAddress.getLocalHost(),9999);
//获取输出流对象
OutputStream outputStream = socket.getOutputStream();
//往输出流中写入信息,发送给服务端
outputStream.write("hello,server".getBytes());
//关闭写入
socket.shutdownOutput();
//获取管道的输入流,获取服务器端发来的信息
InputStream inputStream = socket.getInputStream();
byte[] buf=new byte[1024];
int len = 0;
while ((len = inputStream.read(buf))!=-1){
System.out.println(new String(buf,0,len));
}
//关闭流
inputStream.close();
outputStream.close();
socket.close();
}
}
测试结果
服务端收到信息

客户端收到信息

需求3
使用字符流完成,之前两个需求都是使用的字节流去完成
- 编写一个服务端和一个客户端
- 服务端在9999端口监听
- 客户端连接到服务器,发送"hello,server",并接收服务端回发的"hello,client",退出
- 服务端接收到客户端发送的信息输出,并发送"hello,client",退出
服务端
输出流写入数据后一定要进行flush(),同时进行结束标记
/** * * 服务端 * 需求:使用字符流,接收从客户端发来的信息输出,并返回一条消息给客户端 * * @author:雷子杰 * @date:2022/7/27 */
public class ScoketTCP03Server {
public static void main(String[] args) throws IOException {
//新建serverSocket对象,实现9999端口监听
ServerSocket serverSocket = new ServerSocket(9999);
//客户端连接后会生成管道
Socket socket = serverSocket.accept();
//获取管道的输入流,获取客户端发来的信息
InputStream inputStream = socket.getInputStream();
//将字节流输入流转为字符流输入流
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
char[] cbuf=new char[1024];
int len;
while ((len = inputStreamReader.read(cbuf))!=-1){
System.out.println(new String(cbuf,0,len));
}
//关闭读取
socket.shutdownInput();
//获取输出流对象
OutputStream outputStream = socket.getOutputStream();
//将字节流输出流转换为字符流输出流
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);
//往输出流中写入信息,发送给服务端
outputStreamWriter.write("hello,client");
//需要刷新流后才能写入
outputStreamWriter.flush();
//关闭写入
socket.shutdownOutput();
//关闭流
outputStreamWriter.close();
inputStreamReader.close();
socket.close();
serverSocket.close();
}
}
客户端
输出流写入数据后一定要进行flush(),同时进行结束标记
/** * * 客户端 * 需求:使用字符流,向服务器端发送一条信息,并接收从服务器端返回的一条信息 * * @author:雷子杰 * @date:2022/7/27 */
public class ScoketTCP03Client {
public static void main(String[] args) throws IOException {
//获取socket连接
Socket socket = new Socket(InetAddress.getLocalHost(),9999);
//获取输出流对象
OutputStream outputStream = socket.getOutputStream();
//将字节流输出流转换为字符流输出流
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);
//往输出流中写入信息,发送给服务端
outputStreamWriter.write("hello,server");
//需要刷新流后才能写入
outputStreamWriter.flush();
//关闭写入
socket.shutdownOutput();
//获取管道的输入流,获取服务器端发来的信息
InputStream inputStream = socket.getInputStream();
//将字节流输入流转为字符流输入流
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
char[] cbuf=new char[1024];
int len;
while ((len = inputStreamReader.read(cbuf))!=-1){
System.out.println(new String(cbuf,0,len));
}
//关闭流
inputStreamReader.close();
outputStreamWriter.close();
socket.close();
}
}
测试结果
服务端收到信息

客户端收到信息

发送图片、视频等文件流程说明
由于是图片、视频等文件,所以一定要使用字节流去进行传输
需求:
- 编写一个服务端和一个客户端
- 服务端在8888端口监听
- 客户端连接到服务端,发送本地一张图片
- 服务端接收到客户端发送的图片,保存到src下,发送“收到图片”给客户端,然后退出
- 客户端接收服务端发送的“收到图片”,然后退出
流程示例:
- 客户端使用字节输入流将磁盘中的图片输入到内存中
- 客户端使用字节输出流将内存中的图片输出给服务端
- 服务端使用字节输入流将客户端字节输出流中的图片获取得到
- 服务端使用字节输出流将图片输出到磁盘文件中
服务端
输出流写入数据后一定要进行flush(),同时进行结束标记
/** * * 服务端 * * @author:雷子杰 * @date:2022/7/27 */
public class TCPFileUploadServer {
public static void main(String[] args) throws IOException {
//监听8888端口
ServerSocket serverSocket = new ServerSocket(8888);
//等待连接
Socket socket = serverSocket.accept();
BufferedInputStream bufferedInputStream = new BufferedInputStream(socket.getInputStream());
//创建的字节流输出流
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("basic_review\\src\\socket_\\图片.jpg"));
//读取图片信息
byte[] buf = new byte[1024];
int len;
while ((len = bufferedInputStream.read(buf)) != -1){
bufferedOutputStream.write(buf,0,len);
}
bufferedOutputStream.flush();
socket.shutdownInput();
bufferedOutputStream = new BufferedOutputStream(socket.getOutputStream());
bufferedOutputStream.write("收到图片".getBytes());
//刷新流
bufferedOutputStream.flush();
socket.shutdownOutput();
bufferedOutputStream.close();
bufferedInputStream.close();
socket.close();
serverSocket.close();
}
}
客户端
输出流写入数据后一定要进行flush(),同时进行结束标记
/** * * 客户端 * * @author:雷子杰 * @date:2022/7/27 */
public class TCPFileUploadClient {
public static void main(String[] args) throws IOException {
//连接主机的8888端口,得到socket对象
Socket socket = new Socket(InetAddress.getLocalHost(), 8888);
//读取的文件地址
String filePath ="f:\\ssm博客系统.jpg";
//创建的字节流输入流
BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(filePath));
//创建的字节流输出流
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(socket.getOutputStream());
//读取图片信息
byte[] buf = new byte[1024];
int len;
while ((len = bufferedInputStream.read(buf)) != -1){
//写入到管道中
bufferedOutputStream.write(buf,0,len);
}
//刷新流
bufferedOutputStream.flush();
//关闭写出
socket.shutdownOutput();
bufferedInputStream = new BufferedInputStream(socket.getInputStream());
while ((len = bufferedInputStream.read(buf)) != -1){
System.out.println(new String(buf,0,len));
}
socket.shutdownInput();
bufferedOutputStream.close();
bufferedInputStream.close();
socket.close();
}
}
总结
目前复习java基础复习到了计算机网络阶段,发现自身在网络通信编程这方面的知识较为匮乏,本篇文章用于记载学习java网络编程技术
另外一个重点!!!!!在使用输出流写入数据后一定要进行flush(),同时进行结束标记,否则可能会报错
边栏推荐
- 剖析 kubernetes 集群内部 DNS 解析原理
- 国产口服新冠药阿兹夫定安全吗?专家权威解读
- 数据库系统原理与应用教程(061)—— MySQL 练习题:操作题 21-31(五)
- SAP ui5 fileuploader control realizes local file upload, and trial version of cross domain access error encountered when receiving server-side response
- Map tiles: detailed explanation of vector tiles and grid tiles
- Cesium pit -- pit used by various API calls and API itself
- I miss the year of "losing" Li Ziqi
- Blue Bridge Training (additional interview questions) day 7
- Excellent performance! Oxford, Shanghai, AI Lab, Hong Kong University, Shangtang, and Tsinghua have joined forces to propose a language aware visual transformer for reference image segmentation! Open
- POJ3275 Ranking the Cows题解
猜你喜欢

Continuous (integration -- & gt; delivery -- & gt; deployment)

Customized template in wechat applet

30天刷题计划(三)

倒计时 2 天!2022 中国算力大会:移动云邀您共见算力网络,创新发展

《暗黑破坏神4》PS4/PS5测试版已加入PlayStation数据库

《如何打一场数据挖掘赛事》入门版

Today's sleep quality record 75 points

word打字时后面的字会消失是什么原因?如何解决?

GO语言-栈的应用-表达式求值

Can second uncle cure young people's spiritual internal friction?
随机推荐
Go language - Application of stack - expression evaluation
R语言ggplot2可视化:可视化散点图并为散点图中的数据点添加文本标签、使用ggrepel包的geom_text_repel函数避免数据点标签互相重叠(自定义指定字体类型font family)
屈辱、抗争、逆转,三十年,中国该赢微软一次了
Excellent performance! Oxford, Shanghai, AI Lab, Hong Kong University, Shangtang, and Tsinghua have joined forces to propose a language aware visual transformer for reference image segmentation! Open
Map tiles: detailed explanation of vector tiles and grid tiles
Beyond istio OSS -- current situation and future of istio Service Grid
Tutorial on the principle and application of database system (061) -- MySQL exercise: operation questions 21-31 (V)
R语言可视化散点图、使用ggrepel包的geom_text_repel函数避免数据点之间的标签互相重叠(使用参数xlim和ylim将标签添加到可视化图像的特定区域、指定标签线段并添加箭头)
数据库系统原理与应用教程(058)—— MySQL 练习题(二):单选题
LyScript 获取上一条与下一条指令
Rust 从入门到精通01-简介
火山石投资章苏阳:硬科技,下一个10年相对确定的答案
Children's programming electronic society graphical programming level examination scratch Level 2 real problem analysis (judgment question) June 2022
.NET的求复杂类型集合的差集、交集、并集
org.apache.ibatis.exceptions.TooManyResultsException的异常排查过程
JWT 登录认证 + Token 自动续期方案,写得太好了!
The domestic API management tool eolink is very easy to use, creating an efficient research and development tool
比XShell更好用、更现代的终端工具!
Humiliation, resistance, reversal, 30 years, China should win Microsoft once
What if the server cannot be connected (the original server cannot find the target resource)