Java TCP协议通信超详细讲解

作者:菜鸟小星啦 时间:2021-05-30 20:53:35 

什么是tcp

Tcp通信有两个特点分别是面向连接,具有可靠性.

面向连接:指的是客户端与服务端之间的连接,在通信之前会有三次握手的机制来确保连接的可靠性.

可靠性:tcp在确保他的可靠性上做了许多的功夫,这个可靠性体现在下面两方面:

  • tcp有状态:tcp会精确的纪录哪些数据是发送了的,哪些是没有被发送的,他保证数据包是按序到达的,不允许存在半点差错

  • tcp是可以控制的:如果存在丢包或者网络不好的时候,会根据具体情况对数据包进行发送速度的控制或者对数据包进行重新发送.

如下图是实现服务器端与客户端通信的思路:

Java TCP协议通信超详细讲解

服务端

服务端用到的类是ServerSocket

Java TCP协议通信超详细讲解

ServerSocker类在他的api文档里面也说了他是实现服务器的一个类

了解一个类我们还是老样子先了解他的构造方法,我们看一下api文档

Java TCP协议通信超详细讲解

我们常用的构造方法是第一个ServerSocket()和第二个serverSocket(int port).接下来我们只讲这两个方法.

我们先来讲讲serverSocket()这个构造方法吧!

serverSocket()这个构造方法是创建一个没有绑定端口的对象,一般他和如下方法配套使用

Java TCP协议通信超详细讲解

用以上的方法可以绑定一个你指定的ip地址和端口号.

接下来我们再讲讲第二个常用的构造方法吧 !

ServerSocket(int port)这个构造函数创建的是一个绑定本机的一个自定义端口的一个ServerSocket对象.

如下面的例子

ServerSocket serverSocket = new ServerSocket(6666); //绑定端口号为6666的端口

ServerSocket常用的方法

Java TCP协议通信超详细讲解

accept()方法是一个 * ,是一个阻塞式,它要等有服务端来连接了才能进行下一步,如果没有客户端来连接就会一直等待下去,直到接收到连接才往下运行.这个方法返回的是一个Socket对象,有客户端来连接,就会产生一个Socket对象.这个Socket对象就负责与服务端进行通信

close方法是释放服务器所占用的资源,并且断开全部客户端的连接.

客户端

Socket类是实现客户端通信

接下来我们解析socket

我们就看常用的socket类的构造方法吧

第一个构造方法

Java TCP协议通信超详细讲解

是创建一个连接到的一个指定的ip地址以及指定的端口号的服务器的socket对象.如果你得到的一个Ip地址是一个字符串类型我们还可以使用另一个构造方法

Java TCP协议通信超详细讲解

这个构造方法同样的也是创建一个连接到的一个指定的ip地址以及指定的端口号的服务器的socket对象

我们来看看他的常用方法

Java TCP协议通信超详细讲解

我们这里着重讲的是getOutputStream()方法与getInputStream()

getOutputStream()返回的是一个OutputStream字节输出流对象,我们从这里可以知道我们可以发送数据给服务器/客户端。

getInputStream() 返回有的是InputStream字节输入流对象,我们可以通过这个对象接受服务器/客户端发来的消息。

服务端与客户端代码实现实例

服务端代码

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;
/**
* 服务端
* @author Administrator
*
*/
public class Server {
public static void main(String[] args) {
ServerSocket server = null;
Socket socket = null;
try {
//准备服务器端用的通讯对象(套接字),指明端口号为8888
server = new ServerSocket(8888);
//到指定端口去阻塞监听,一旦有客户端请求发送过来,那么立即自动与客户端建立连接
socket = server.accept();
System.out.println("服务器端准备ok");
//我要发送到客户端的内容
String msg = "你好,我是服务器,这是我的第一次通讯,请问你收到了吗";
OutputStream os = socket.getOutputStream();//准备输出对象
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
bw.write(msg);
bw.newLine();
bw.flush();
//接收客户端发送的信息
InputStream is = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String reply = br.readLine();
System.out.println("我是服务器,接收到信息:"+reply);
br.close();
is.close();
bw.close();
os.close();
socket.close();
server.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

客户端代码

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;
import java.net.UnknownHostException;
/**
* 客户端
* @author Administrator
*
*/
public class Client {
public static void main(String[] args) {
Socket socket = null;
try {
socket = new Socket("localhost", 8888);
System.out.println("客户端准备完成");
//客户端开始接受请求
InputStream is = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String msg = br.readLine();
System.out.println("我是客户端,接收到信息:"+msg);
//客户端接收到服务器端的信息之后,需要反馈信息给服务器
       //客户端想要反馈给服务器端的信息
String reply = "我是客户端,收到你的信息,这是我的反馈";
OutputStream os = socket.getOutputStream();//准备客户端的输出流
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
bw.write(reply);
bw.newLine();
bw.flush();
bw.close();
os.close();
br.close();
is.close();
socket.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}

来源:https://blog.csdn.net/m0_48844699/article/details/126614414

标签:Java,TCP,协议,通信
0
投稿

猜你喜欢

  • springboot日期转换器实现实例解析

    2023-01-31 13:16:45
  • C#字符集编码的使用及说明

    2023-12-05 02:06:05
  • Intellij IDEA根据maven依赖名查找它是哪个pom.xml引入的(图文详解)

    2023-07-20 07:49:35
  • 升级dubbo2.7.4.1版本平滑迁移到注册中心nacos

    2021-11-17 04:03:34
  • C# WebApi 路由机制剖析

    2022-01-23 05:20:16
  • 如何使用SpringSecurity保护程序安全

    2022-09-08 19:57:50
  • java 中 System.out.println()和System.out.write()的区别

    2021-09-17 04:30:52
  • ref与out之间的区别深入解析

    2023-08-05 23:45:28
  • Android完整Socket解决方案

    2023-12-22 14:42:40
  • C# pictureBox用法案例详解

    2022-02-24 19:40:07
  • WebView的几个常见功能使用方法

    2023-01-25 13:54:48
  • Java 实现网络爬虫框架详细代码

    2021-12-11 05:15:43
  • SpringBoot集成JmsTemplate(队列模式和主题模式)及xml和JavaConfig配置详解

    2022-01-31 05:29:10
  • Java反射如何修改private final成员变量值

    2023-09-06 03:43:18
  • Android 无障碍服务 performAction 调用过程分析

    2023-05-03 12:06:17
  • java中functional interface的分类和使用详解

    2021-09-15 15:59:20
  • Josephus环的四种解法(约瑟夫环)基于java详解

    2022-02-28 23:29:13
  • WPF实现雷达图(仿英雄联盟)的示例代码

    2023-07-13 18:46:53
  • 程序猿必须要掌握的多线程安全问题之锁策略详解

    2021-10-19 04:57:17
  • 详解Java中使用泛型实现快速排序算法的方法

    2022-04-28 09:47:00
  • asp之家 软件编程 m.aspxhome.com