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

网友投稿 263 2022-09-24


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

目录Socket连接模型消息协议传输过程中数据类型需要了解的细节TCP通信代码

上篇教程回顾

ServerSocket --监听客户端的连接,他的作用主要是建立一个连接

-ServerSocket -建立连接,拿到一个Socket

-Telnet 127.0.0.1 8888- 客户端使用Telnet访问服务端 建立连接

-服务端可以拿到一个Socket的对象

-获取这个对象的输入输出流

-写入和读取数据

Socket连接模型

服务端和客户端通过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通信http://代码

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

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="服务器连接成功!!!中秋快乐! 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());

// }

}

}

运行结果

还可以完善的地方

1、之后通信协议可以加入,通过客户端列表,转发消息内容到多个客户端

2、携带用户名、目标用户名等等


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:OSPF虚链路部署——实战可一步步跟做(ospf虚链路是什么)
下一篇:OSPF动态路由协议之——虚链路(ospf协议域内路由协议)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~