服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Java教程 - Java后端学习精华之TCP通信传输协议详解

Java后端学习精华之TCP通信传输协议详解

2022-01-21 11:57冷丁_ Java教程

TCP/IP是一种面向连接的、可靠的、基于字节流的传输层通信协议,它会保证数据不丢包、不乱序。TCP全名是Transmission Control Protocol,它是位于网络OSI模型中的第四层

上篇教程回顾

ServerSocket --监听客户端的连接,他的作用主要是建立一个连接
-ServerSocket -建立连接,拿到一个Socket
-Telnet 127.0.0.1 8888- 客户端使用Telnet访问服务端 建立连接
-服务端可以拿到一个Socket的对象
-获取这个对象的输入输出流
-写入和读取数据

 

Socket连接模型

Java后端学习精华之TCP通信传输协议详解

服务端和客户端通过Socket进行连接,虽然是一个Socket,但是相当于把这一个Socket分成了两个管道,服务端拿着这两根管道的一段,客户端拿着这两根管道的另一端。

  • Server的input与Client的output相连
  • 客户端发送数据,从Client的output发送,传输到Server的input接收
  • 服务端发送数据,从Server的output发送,传输到Client的input接收
  • 如果实现双端收发通信,每个程序至少需要两个线程

 

消息协议

TCP:面向连接
UDP:不需要建立连接 类似数据报

TCP:稳定,要求发送数据前必须确认双方都可以收发消息
连接过程 : 三次握手
Server--------------------- Client

1: 监听-----------------------发送请求
这步之后,服务端知道客户端可以发数据
2:收到请求,应答------------收到应答消息,发送应答包给s
这步之后,客户端知道服务端可收发数据
3:收到应答
这步之后,服务端知道客户端可以收数据

 

传输过程中数据类型需要了解的细节

char:16bit 两个字节Byte

数据发送的单位:数据每次发送一个byte,一个char需要发送两次单字节

发送文字消息

  • 第一部分应发送字符串的长度,以便确定字节数组的长度
  • 对方,读取的第一个字节是消息长度,定义一个固定容量大小的容器
  • 第二部分为消息内容
  • 对方,读取对应长度的字节后,将其转成对应的数据(String对象)

数据类型:

  • 整数型:byte short int long
  • 浮点型:float double
  • 字符型:char
  • 布尔型:boolean
  • char=16bit=2 byte unicode编码
  • utf-8:1-6个字节组成一个汉字

1100 1101 1010

如这个数据第一个字节有两个1,则代表它是一个汉子,并且后面两个字节都表示这个汉字,如果有111就读取后面三个字节
因为英文用ASCII码存储0-127,第一位不可能是1,通过第一个字节可以判断是中文还是英文

  • 英文字母全部兼容:ASCII 0-127 二进制码:0-255,所以0-127一定以0开头,汉字是16bit 0-65536

 

TCP通信代码

通过自己编写一个客户端和服务端,实现消息的首发,这里的核心主要是自己编写通信协议,我在这里第一次发送到是数据的长度,并且做了数据加密,客户端需要解析这个数据长度,并创建对应长度的数组,才能正确读取消息内容
MsgClient

package com.lding.net;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

/**
* @program: Net
* @description: Tcp客户端测试
* @author: 王丁
* @date: 2021-09-20 10:04
**/
public class TcpClient {
  public static void main(String[] args) throws IOException {
      Socket socket=new Socket("127.0.0.1",8888);
      OutputStream output=socket.getOutputStream();
      InputStream input=socket.getInputStream();
      InputStreamReader inputStreamReader = new InputStreamReader(input);

//        byte[] msgbyte=new byte[30];
//        input.read(msgbyte);
//        System.out.println("服务器说:"+new String(msgbyte));

      int length1=input.read();
      int length2=input.read();
      int msglength=length2*3+length1;
      System.out.println("消息长度为:"+msglength);
      byte[] msgbytes=new byte[msglength];
      input.read(msgbytes);
      String getmsg=new String(msgbytes);
      System.out.println("服务器说:"+getmsg);

  }
}

MsgServer

package com.lding.net;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

/**
* @program: Net
* @description: Tcp服务端测试
* @author: 王丁
* @date: 2021-09-20 10:03
**/
public class TcpServer {
  public static void main(String[] args) throws IOException {
      ServerSocket serverSocket = new ServerSocket(8888);
      //监听客户端的Socket连接
      System.out.println("服务端开启:ip:"+serverSocket.getInetAddress().getHostAddress()+"端口号:"+serverSocket.getLocalSocketAddress());
      System.out.println("正在等待有缘人......");
      Socket socketClient = serverSocket.accept();
      System.out.println("客户端已连接:"+socketClient.getInetAddress());
      System.out.println("客户端端口"+socketClient.getPort());

      OutputStream output=socketClient.getOutputStream();
      InputStream input=socketClient.getInputStream();

//        output.write("服务器连接成功!!!".getBytes());
//        output.flush();//刷新缓冲,管道强制刷出
      String msg="服务器连接成功!!!中秋快乐!<include/bits/stdc++.h> using namespace std";
      byte[] msgBytes=msg.getBytes();
      int length1=msgBytes.length%3;
      int length2=msgBytes.length/3;
      output.write(length1);
      output.write(length2);
      output.write(msgBytes);
      output.flush();
//        while(input.read()!=-1){
//            System.out.println((char) input.read());
//        }
  }
}

运行结果

Java后端学习精华之TCP通信传输协议详解

Java后端学习精华之TCP通信传输协议详解

还可以完善的地方

1、之后通信协议可以加入,通过客户端列表,转发消息内容到多个客户端
2、携带用户名、目标用户名等等

到此这篇关于Java后端学习精华之TCP通信传输协议详解的文章就介绍到这了,更多相关Java TCP通信内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/qq_41359998/article/details/120391239

延伸 · 阅读

精彩推荐
  • Java教程Java8中Stream使用的一个注意事项

    Java8中Stream使用的一个注意事项

    最近在工作中发现了对于集合操作转换的神器,java8新特性 stream,但在使用中遇到了一个非常重要的注意点,所以这篇文章主要给大家介绍了关于Java8中S...

    阿杜7482021-02-04
  • Java教程20个非常实用的Java程序代码片段

    20个非常实用的Java程序代码片段

    这篇文章主要为大家分享了20个非常实用的Java程序片段,对java开发项目有所帮助,感兴趣的小伙伴们可以参考一下 ...

    lijiao5352020-04-06
  • Java教程Java使用SAX解析xml的示例

    Java使用SAX解析xml的示例

    这篇文章主要介绍了Java使用SAX解析xml的示例,帮助大家更好的理解和学习使用Java,感兴趣的朋友可以了解下...

    大行者10067412021-08-30
  • Java教程小米推送Java代码

    小米推送Java代码

    今天小编就为大家分享一篇关于小米推送Java代码,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧...

    富贵稳中求8032021-07-12
  • Java教程升级IDEA后Lombok不能使用的解决方法

    升级IDEA后Lombok不能使用的解决方法

    最近看到提示IDEA提示升级,寻思已经有好久没有升过级了。升级完毕重启之后,突然发现好多错误,本文就来介绍一下如何解决,感兴趣的可以了解一下...

    程序猿DD9332021-10-08
  • Java教程xml与Java对象的转换详解

    xml与Java对象的转换详解

    这篇文章主要介绍了xml与Java对象的转换详解的相关资料,需要的朋友可以参考下...

    Java教程网2942020-09-17
  • Java教程Java实现抢红包功能

    Java实现抢红包功能

    这篇文章主要为大家详细介绍了Java实现抢红包功能,采用多线程模拟多人同时抢红包,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙...

    littleschemer13532021-05-16
  • Java教程Java BufferWriter写文件写不进去或缺失数据的解决

    Java BufferWriter写文件写不进去或缺失数据的解决

    这篇文章主要介绍了Java BufferWriter写文件写不进去或缺失数据的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望...

    spcoder14552021-10-18