当前位置: 首页 > news >正文

ps做网站顶部免费的行情网站app软件

ps做网站顶部,免费的行情网站app软件,上海外贸界龙彩印有限公司,国内做设备网站哪些好目录 概述TCP连接可靠性1. 三次握手过程2. 四次挥手过程3. 为什么挥手需要四次? 传输可靠性TCP核心APITCP传输初始化配置&建立连接客户端创建Socket建立连接服务端创建ServerSocket监听连接ServerSocket 和 Socket的关系 Socket基本数据类型传输客户端数据传输服…

概述

  1. TCP是什么
    英语:Transmission Control Protocol,缩写为 TCP
    TCP是传输控制协议;是一种面向连接的、可靠的、基于字节流的传输层通信协议,由IETF的RFC 793定义
    与UDP一样完成第四层传输层所指定的功能与职责

  2. TCP的机制
    三次握手、四次挥手
    具有校验机制、可靠、数据传输稳定

  3. TCP能做什么
    聊天消息传输、推送
    单人语音、视频聊天等
    几乎UDP能做的都能做,但需要考虑复杂性、性能问题
    限制:无法进行广播,多播等操作

TCP连接可靠性

1. 三次握手过程

20240228-020352-Ph.png
三次握手的过程包括:

第一次握手:客户端发送SYN包,携带自己的序列号。
第二次握手:服务器端回复SYN+ACK包,确认收到客户端的SYN包,并携带自己的序列号。
第三次握手:客户端回复ACK包,确认收到的SYN+ACK包,完成握手过程。

这个过程确保了后续数据的可靠传输和完整性,保障了网络通信的稳定性和可靠性。

2. 四次挥手过程

20240228-020858-ym.png
四次挥手是TCP协议中用于终止连接的过程,这个过程涉及到客户端和服务端之间发送四个数据包。由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。在四次挥手中,首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭。1234

以下是四次挥手的详细步骤:

第一次挥手:客户端发送一个FIN报文,用来关闭客户端到服务器的数据传送。此时客户端进入FIN_WAIT_1状态.
第二次挥手:服务器收到FIN报文后,发送一个ACK报文作为响应,确认序号为收到序号加1。此时服务器进入CLOSE_WAIT状态。
第三次挥手:服务器完成数据发送任务后,发送一个FIN报文,用来关闭服务器到客户端的数据传送。此时服务器进入LAST_ACK状态。
第四次挥手:客户端收到FIN报文后,发送一个ACK报文作为响应,确认序号为收到序号加1。此时客户端进入TIME_WAIT状态。客户端在等待一段时间(通常为2MSL,即最大报文段寿命)后,如果没有收到服务器的任何响应,则进入CLOSE状态。

这个过程确保了双方都能正确关闭连接,避免了数据丢失。

3. 为什么挥手需要四次?

由于 TCP 的半关闭(half-close)特性,TCP 提供了连接的一端在结束它的发送后还能接收来自另一端数据的能力。

任何一方都可以在数据传送结束后发出连接释放的通知,待对方确认后进入半关闭状态。当另一方也没有数据再发送的时候,则发出连接释放通知,对方确认后就完全关闭了TCP连接。
通俗的来说,两次握手就可以释放一端到另一端的 TCP 连接,完全释放连接一共需要四次握手。

可以用下面这个例子理解:

举个例子:A 和 B 打电话,通话即将结束后,A 说 “我没啥要说的了”,B 回答 “我知道了”,于是 A 向 B 的连接释放了。但是 B 可能还会有要说的话,于是 B 可能又巴拉巴拉说了一通,最后 B 说“我说完了”,A 回答“知道了”,于是 B 向 A 的连接释放了,这样整个通话就结束了。

传输可靠性

  1. 排序、顺序发送、顺序组装
  2. 丢弃、超时
  3. 重发机制-定时器

数据传输示意图
20240228-022539-2k.png

TCP核心API

socket():创建—个Socket
bind():绑定一个Socket到一个本地地址和端口上
connect():连接到远程套接字
accept():接受一个新的连接
write():把数据写入到Socket输出流
read():从Socket输入流读取数据

客户端Socket创建流程:
20240228-013916-lO.png

服务端ServerSocket创建流程:
20240228-014016-IO.png

Socket和进程的关系:
20240228-014241-Xq.png

TCP传输初始化配置&建立连接

  1. 初始化服务器TCP链接监听
  2. 初始化客户端发起链接操作
  3. 服务器Socket链接处理

客户端创建Socket建立连接

  1. 创建Socket基本方法和构造函数
private static Socket createSocket() throws IOException {/*// 无代理模式,等效于空构造函数Socket socket = new Socket(Proxy.NO_PROXY);// 新建一份具有HTTP代理的套接字,传输数据将通过www.baidu.com:8080端口转发Proxy proxy = new Proxy(Proxy.Type.HTTP,new InetSocketAddress(Inet4Address.getByName("www.baidu.com"), 8800));socket = new Socket(proxy);// 新建一个套接字,并且直接链接到本地20000的服务器上socket = new Socket("localhost", PORT);// 新建一个套接字,并且直接链接到本地20000的服务器上socket = new Socket(Inet4Address.getLocalHost(), PORT);// 新建一个套接字,并且直接链接到本地20000的服务器上,并且绑定到本地20001端口上socket = new Socket("localhost", PORT, Inet4Address.getLocalHost(), LOCAL_PORT);socket = new Socket(Inet4Address.getLocalHost(), PORT, Inet4Address.getLocalHost(), LOCAL_PORT);*/Socket socket = new Socket();// 绑定到本地20001端口socket.bind(new InetSocketAddress(Inet4Address.getLocalHost(), LOCAL_PORT));return socket;}
  1. 初始化Socket的基本配置
private static void initSocket(Socket socket) throws SocketException {// 设置读取超时时间为2秒socket.setSoTimeout(2000);// 是否复用未完全关闭的Socket地址,对于指定bind操作后的套接字有效socket.setReuseAddress(true);// 是否开启Nagle算法socket.setTcpNoDelay(true);// 是否需要在长时无数据响应时发送确认数据(类似心跳包),时间大约为2小时socket.setKeepAlive(true);// 对于close关闭操作行为进行怎样的处理;默认为false,0// false、0:默认情况,关闭时立即返回,底层系统接管输出流,将缓冲区内的数据发送完成// true、0:关闭时立即返回,缓冲区数据抛弃,直接发送RST结束命令到对方,并无需经过2MSL等待// true、200:关闭时最长阻塞200毫秒,随后按第二情况处理socket.setSoLinger(true, 20);// 是否让紧急数据内敛,默认false;紧急数据通过 socket.sendUrgentData(1);发送socket.setOOBInline(true);// 设置接收发送缓冲器大小socket.setReceiveBufferSize(64 * 1024 * 1024);socket.setSendBufferSize(64 * 1024 * 1024);// 设置性能参数:短链接,延迟,带宽的相对重要性socket.setPerformancePreferences(1, 1, 0);}
  1. 客户端手动连接
public static void main(String[] args) throws IOException {Socket socket = createSocket();initSocket(socket);// 链接到本地20000端口,超时时间3秒,超过则抛出超时异常socket.connect(new InetSocketAddress(Inet4Address.getLocalHost(), PORT), 3000);System.out.println("已发起服务器连接,并进入后续流程~");System.out.println("客户端信息:" + socket.getLocalAddress() + " P:" + socket.getLocalPort());System.out.println("服务器信息:" + socket.getInetAddress() + " P:" + socket.getPort());try {// 发送接收数据todo(socket);} catch (Exception e) {System.out.println("异常关闭");}// 释放资源socket.close();System.out.println("客户端已退出~");}

服务端创建ServerSocket监听连接

  1. 创建ServerSocket方法
private static ServerSocket createServerSocket() throws IOException {// 创建基础的ServerSocketServerSocket serverSocket = new ServerSocket();// 绑定到本地端口20000上,并且设置当前可允许等待链接的队列为50个//serverSocket = new ServerSocket(PORT);// 等效于上面的方案,队列设置为50个//serverSocket = new ServerSocket(PORT, 50);// 与上面等同// serverSocket = new ServerSocket(PORT, 50, Inet4Address.getLocalHost());return serverSocket;}
  1. 初始化ServerSocket配置
private static void initServerSocket(ServerSocket serverSocket) throws IOException {// 是否复用未完全关闭的地址端口serverSocket.setReuseAddress(true);// 等效Socket#setReceiveBufferSizeserverSocket.setReceiveBufferSize(64 * 1024 * 1024);// 设置serverSocket#accept超时时间// serverSocket.setSoTimeout(2000);// 设置性能参数:短链接,延迟,带宽的相对重要性serverSocket.setPerformancePreferences(1, 1, 1);}
  1. 监听服务端固定端口,并且接受客户端建立连接
private static final int PORT = 20000;public static void main(String[] args) throws IOException {ServerSocket server = createServerSocket();initServerSocket(server);// 绑定到本地端口上server.bind(new InetSocketAddress(Inet4Address.getLocalHost(), PORT), 50);System.out.println("服务器准备就绪~");System.out.println("服务器信息:" + server.getInetAddress() + " P:" + server.getLocalPort());// 等待客户端连接for (; ; ) {// 得到客户端Socket client = server.accept();// 客户端构建异步线程ClientHandler clientHandler = new ClientHandler(client);// 启动线程clientHandler.start();}}

ServerSocket 和 Socket的关系

serverSocket 和 Socket 都是 Java 中用于网络通信的类,但它们有不同的作用。

Socket 是用于建立连接的类,它可以让客户端和服务器之间相互通信。

ServerSocket 是用于监听连接请求的类,它在服务器端等待客户端的连接请求,并在连接成功后与客户端建立对应的 Socket 连接。

具体工作原理可以简单描述为:

当客户端与服务器建立连接时,客户端通过创建 Socket 对象实现,服务器端则通过创建 ServerSocket 对象实现。
客户端向服务器发送连接请求,请求中包含了要连接的服务器地址和端口号。
ServerSocket 接收到连接请求后,会生成一个 Socket 对象与客户端连接,并返回此连接对应的 Socket 对象。
客户端和服务器之间即可通过这个连接进行通信。

总之,ServerSocket 是用于监听连接请求的类,而 Socket 则是用于实现连接并进行通信的类。

Socket基本数据类型传输

基础类型数据传输

  • byte、 char、 short
  • boolean、 int、 long
  • float、 double、 string

客户端数据传输

  1. 客户端使用Socket输出流将客户端的数据传输出去
  2. 建立连接之后将各种数据类型的数据转换成byte字节数组,然后通过ByteBuffer工具统一放入字节流
    (这里使用到了一个ByteBuffer工具,这是一个字节缓冲区,后面会详细介绍)
  3. 最后通过Socket的输出流把数据发送给服务端

代码如下:

private static void todo(Socket client) throws IOException {// 得到Socket输出流OutputStream outputStream = client.getOutputStream();// 得到Socket输入流InputStream inputStream = client.getInputStream();byte[] buffer = new byte[256];ByteBuffer byteBuffer = ByteBuffer.wrap(buffer);// bytebyteBuffer.put((byte) 126);// charchar c = 'a';byteBuffer.putChar(c);// intint i = 2323123;byteBuffer.putInt(i);// boolboolean b = true;byteBuffer.put(b ? (byte) 1 : (byte) 0);// Longlong l = 298789739;byteBuffer.putLong(l);// floatfloat f = 12.345f;byteBuffer.putFloat(f);// doubledouble d = 13.31241248782973;byteBuffer.putDouble(d);// StringString str = "Hello你好!";byteBuffer.put(str.getBytes());// 发送到服务器outputStream.write(buffer, 0, byteBuffer.position() + 1);// 接收服务器返回int read = inputStream.read(buffer);System.out.println("收到数量:" + read);// 资源释放outputStream.close();inputStream.close();}

服务端数据接收

  1. 获取监听到连接的客户端Socket套接字流
  2. 将流读取出来,转换成ByteBuffer
  3. 最后根据不同的数据类型将ByteBuffer中的数据读取并且打印出来
/*** 客户端消息处理*/private static class ClientHandler extends Thread {private Socket socket;ClientHandler(Socket socket) {this.socket = socket;}@Overridepublic void run() {super.run();System.out.println("新客户端连接:" + socket.getInetAddress() +" P:" + socket.getPort());try {// 得到套接字流OutputStream outputStream = socket.getOutputStream();InputStream inputStream = socket.getInputStream();byte[] buffer = new byte[256];int readCount = inputStream.read(buffer);ByteBuffer byteBuffer = ByteBuffer.wrap(buffer, 0, readCount);// bytebyte be = byteBuffer.get();// charchar c = byteBuffer.getChar();// intint i = byteBuffer.getInt();// boolboolean b = byteBuffer.get() == 1;// Longlong l = byteBuffer.getLong();// floatfloat f = byteBuffer.getFloat();// doubledouble d = byteBuffer.getDouble();// Stringint pos = byteBuffer.position();String str = new String(buffer, pos, readCount - pos - 1);System.out.println("收到数量:" + readCount + " 数据:"+ be + "\n"+ c + "\n"+ i + "\n"+ b + "\n"+ l + "\n"+ f + "\n"+ d + "\n"+ str + "\n");outputStream.write(buffer, 0, readCount);outputStream.close();inputStream.close();} catch (Exception e) {System.out.println("连接异常断开");} finally {// 连接关闭try {socket.close();} catch (IOException e) {e.printStackTrace();}}System.out.println("客户端已退出:" + socket.getInetAddress() +" P:" + socket.getPort());}}

TCP连接客户端、服务端完整代码

服务端代码:

package cn.kt.SocketDemoL4;import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Inet4Address;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.ByteBuffer;public class Server {private static final int PORT = 20000;public static void main(String[] args) throws IOException {ServerSocket server = createServerSocket();initServerSocket(server);// 绑定到本地端口上server.bind(new InetSocketAddress(Inet4Address.getLocalHost(), PORT), 50);System.out.println("服务器准备就绪~");System.out.println("服务器信息:" + server.getInetAddress() + " P:" + server.getLocalPort());// 等待客户端连接for (; ; ) {// 得到客户端Socket client = server.accept();// 客户端构建异步线程ClientHandler clientHandler = new ClientHandler(client);// 启动线程clientHandler.start();}}private static ServerSocket createServerSocket() throws IOException {// 创建基础的ServerSocketServerSocket serverSocket = new ServerSocket();// 绑定到本地端口20000上,并且设置当前可允许等待链接的队列为50个//serverSocket = new ServerSocket(PORT);// 等效于上面的方案,队列设置为50个//serverSocket = new ServerSocket(PORT, 50);// 与上面等同// serverSocket = new ServerSocket(PORT, 50, Inet4Address.getLocalHost());return serverSocket;}private static void initServerSocket(ServerSocket serverSocket) throws IOException {// 是否复用未完全关闭的地址端口serverSocket.setReuseAddress(true);// 等效Socket#setReceiveBufferSizeserverSocket.setReceiveBufferSize(64 * 1024 * 1024);// 设置serverSocket#accept超时时间// serverSocket.setSoTimeout(2000);// 设置性能参数:短链接,延迟,带宽的相对重要性serverSocket.setPerformancePreferences(1, 1, 1);}/*** 客户端消息处理*/private static class ClientHandler extends Thread {private Socket socket;ClientHandler(Socket socket) {this.socket = socket;}@Overridepublic void run() {super.run();System.out.println("新客户端连接:" + socket.getInetAddress() +" P:" + socket.getPort());try {// 得到套接字流OutputStream outputStream = socket.getOutputStream();InputStream inputStream = socket.getInputStream();byte[] buffer = new byte[256];int readCount = inputStream.read(buffer);ByteBuffer byteBuffer = ByteBuffer.wrap(buffer, 0, readCount);// bytebyte be = byteBuffer.get();// charchar c = byteBuffer.getChar();// intint i = byteBuffer.getInt();// boolboolean b = byteBuffer.get() == 1;// Longlong l = byteBuffer.getLong();// floatfloat f = byteBuffer.getFloat();// doubledouble d = byteBuffer.getDouble();// Stringint pos = byteBuffer.position();String str = new String(buffer, pos, readCount - pos - 1);System.out.println("收到数量:" + readCount + " 数据:"+ be + "\n"+ c + "\n"+ i + "\n"+ b + "\n"+ l + "\n"+ f + "\n"+ d + "\n"+ str + "\n");outputStream.write(buffer, 0, readCount);outputStream.close();inputStream.close();} catch (Exception e) {System.out.println("连接异常断开");} finally {// 连接关闭try {socket.close();} catch (IOException e) {e.printStackTrace();}}System.out.println("客户端已退出:" + socket.getInetAddress() +" P:" + socket.getPort());}}
}

客户端代码

package cn.kt.SocketDemoL4;import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Inet4Address;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketException;
import java.nio.ByteBuffer;public class Client {private static final int PORT = 20000;private static final int LOCAL_PORT = 20001;public static void main(String[] args) throws IOException {Socket socket = createSocket();initSocket(socket);// 链接到本地20000端口,超时时间3秒,超过则抛出超时异常socket.connect(new InetSocketAddress(Inet4Address.getLocalHost(), PORT), 3000);System.out.println("已发起服务器连接,并进入后续流程~");System.out.println("客户端信息:" + socket.getLocalAddress() + " P:" + socket.getLocalPort());System.out.println("服务器信息:" + socket.getInetAddress() + " P:" + socket.getPort());try {// 发送接收数据todo(socket);} catch (Exception e) {System.out.println("异常关闭");}// 释放资源socket.close();System.out.println("客户端已退出~");}private static Socket createSocket() throws IOException {/*// 无代理模式,等效于空构造函数Socket socket = new Socket(Proxy.NO_PROXY);// 新建一份具有HTTP代理的套接字,传输数据将通过www.baidu.com:8080端口转发Proxy proxy = new Proxy(Proxy.Type.HTTP,new InetSocketAddress(Inet4Address.getByName("www.baidu.com"), 8800));socket = new Socket(proxy);// 新建一个套接字,并且直接链接到本地20000的服务器上socket = new Socket("localhost", PORT);// 新建一个套接字,并且直接链接到本地20000的服务器上socket = new Socket(Inet4Address.getLocalHost(), PORT);// 新建一个套接字,并且直接链接到本地20000的服务器上,并且绑定到本地20001端口上socket = new Socket("localhost", PORT, Inet4Address.getLocalHost(), LOCAL_PORT);socket = new Socket(Inet4Address.getLocalHost(), PORT, Inet4Address.getLocalHost(), LOCAL_PORT);*/Socket socket = new Socket();// 绑定到本地20001端口socket.bind(new InetSocketAddress(Inet4Address.getLocalHost(), LOCAL_PORT));return socket;}private static void initSocket(Socket socket) throws SocketException {// 设置读取超时时间为2秒socket.setSoTimeout(2000);// 是否复用未完全关闭的Socket地址,对于指定bind操作后的套接字有效socket.setReuseAddress(true);// 是否开启Nagle算法socket.setTcpNoDelay(true);// 是否需要在长时无数据响应时发送确认数据(类似心跳包),时间大约为2小时socket.setKeepAlive(true);// 对于close关闭操作行为进行怎样的处理;默认为false,0// false、0:默认情况,关闭时立即返回,底层系统接管输出流,将缓冲区内的数据发送完成// true、0:关闭时立即返回,缓冲区数据抛弃,直接发送RST结束命令到对方,并无需经过2MSL等待// true、200:关闭时最长阻塞200毫秒,随后按第二情况处理socket.setSoLinger(true, 20);// 是否让紧急数据内敛,默认false;紧急数据通过 socket.sendUrgentData(1);发送socket.setOOBInline(true);// 设置接收发送缓冲器大小socket.setReceiveBufferSize(64 * 1024 * 1024);socket.setSendBufferSize(64 * 1024 * 1024);// 设置性能参数:短链接,延迟,带宽的相对重要性socket.setPerformancePreferences(1, 1, 0);}private static void todo(Socket client) throws IOException {// 得到Socket输出流OutputStream outputStream = client.getOutputStream();// 得到Socket输入流InputStream inputStream = client.getInputStream();byte[] buffer = new byte[256];ByteBuffer byteBuffer = ByteBuffer.wrap(buffer);// bytebyteBuffer.put((byte) 126);// charchar c = 'a';byteBuffer.putChar(c);// intint i = 2323123;byteBuffer.putInt(i);// boolboolean b = true;byteBuffer.put(b ? (byte) 1 : (byte) 0);// Longlong l = 298789739;byteBuffer.putLong(l);// floatfloat f = 12.345f;byteBuffer.putFloat(f);// doubledouble d = 13.31241248782973;byteBuffer.putDouble(d);// StringString str = "Hello你好!";byteBuffer.put(str.getBytes());// 发送到服务器outputStream.write(buffer, 0, byteBuffer.position() + 1);// 接收服务器返回int read = inputStream.read(buffer);System.out.println("收到数量:" + read);// 资源释放outputStream.close();inputStream.close();}
}

执行结果

  1. 运行服务端
    20240228-151715-ZN.png

  2. 运行客户端
    20240228-151741-r9.png

  3. 服务端接收到消息并输出

20240228-151758-6Y.png

http://www.yidumall.com/news/67907.html

相关文章:

  • wordpress配置数据库seo项目优化案例分析文档
  • 写出网站开发的基本流程网站排名优化技巧
  • 如何注册小程序开店站长工具seo推广 站长工具查询
  • 现代感网站百度学术论文查重
  • 哈尔滨企业网站建站推荐app定制开发
  • 百度权重查询网站今天国内新闻10条
  • 360安全网站怎么做号码认证营销的手段和方法
  • 怎么做代刷网站网络营销课程培训
  • 阿里云建站和华为云建站哪个好安卓优化大师旧版本下载
  • 津南区提供网站建设协议制作网站推广
  • 图书馆网站开发策划书嘉兴seo计费管理
  • 建设银行临夏分行网站广西南宁做网站的公司
  • wordpress海外支付宝站长工具seo综合
  • 传奇霸主页游东莞seo优化排名
  • 专业企业网站开发公司长沙网站优化对策
  • 动态网站留言板怎么做莱阳seo排名
  • 网站推广网站网络推广代理怎么做
  • django做企业级网站如何在百度上添加店铺的位置
  • 国内最好的网站建设公司广州网络推广定制
  • 大朗网站仿做5118
  • 网站添加客服国外搜索引擎入口
  • 做衬衫的作业网站武汉seo服务
  • 杭州市城乡建设委员会的网站买卖平台
  • 网站上广告如何进行seo
  • 出效果图重庆网站seo好不好
  • 软件代理威海seo优化公司
  • 除了做视频网站还能做什么网站qq刷赞网站推广
  • 做网站有哪些平台站长工具怎么关掉
  • 网站的建设百度公司总部地址
  • 免费自制网站建设网店代运营骗局