Java后端学习精华之TCP通信传输协议详解
作者:冷丁_ 发布时间:2021-08-06 03:15:42
上篇教程回顾
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通信代码
通过自己编写一个客户端和服务端,实现消息的首发,这里的核心主要是自己编写通信协议,我在这里第一次发送到是数据的长度,并且做了数据加密,客户端需要解析这个数据长度,并创建对应长度的数组,才能正确读取消息内容
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());
// }
}
}
运行结果
还可以完善的地方
1、之后通信协议可以加入,通过客户端列表,转发消息内容到多个客户端
2、携带用户名、目标用户名等等
来源:https://blog.csdn.net/qq_41359998/article/details/120391239


猜你喜欢
- 废话不多说了,直接给大家贴代码了。具体代码如下所示:using System;using System.Collections.Generi
- 仿QQ侧滑删除效果图1.自定义listviewpublic class DragDelListView extends ListView {
- 在有些需求中会遇到,当鼠标滑过某个UI物体上方时,为了提醒用户该物体是可以交互时,我们需要添加一个动效和提示音。这样可以提高产品的体验感。解
- 今年新开Java课程第一步就是…配置环境就从Java的环境配置开始好了以下是正式的步骤首先,从Oracle的官网下载jdk的安装包点我下载J
- 看到当上面的对话框弹出时,可以使用命令查看顶层的活动窗口adb shell dumpsys window | findstr mCurren
- 本文实例讲述了Android的三种菜单。分享给大家供大家参考。具体分析如下:Android的菜单分为三种类型:选项菜单(Option Men
- 介绍在 .NET4.0 之前,如果我们需要在多线程环境下使用 Dictionary 类,除了自己实现线程同步来保证线程安全外,我们没有其他选
- 函数指针是指向函数的指针,指针函数是指一个函数的返回值是一个指针,但下面的几道题还是感觉很迷惑。各位能否讲的详细点呢?(1) float(*
- 约瑟夫环约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数
- Q1: Object类型包含哪些方法?A1: Object类型共包含6个方法,Equals, GetHashCode, ToString,
- 前言代码库:https://gitee.com/leo825/springboot-learning-parents.git之前写过《Spr
- 实现效果:Form1.cs代码:using System;using System.Collections.Generic;using Sy
- 一、语音聊天说专业点就是即时语音,是一种基于网络的快速传递语音信息的技术,普遍应用于各类社交软件中,优势主要有以下几点:(1)时效性:视频直
- 一、模糊查询的几种实现方式1.concat函数和#{}拼接的方式student_name like concat('%',#
- 一、首先我们先大致了解一下什么是多线程。(书上的解释)程序是一段静态的代码,它是应用软件的蓝本。进程是程序的一次动态执行过程,对
- 关于[Cannot determine value type from string ‘xxx’]的
- 1.线程的几种状态1.1 线程的状态以下就是我们线程所有的状态和意义:NEW已经创建Thread但未创建线程RUNNABLE可工作的. 又可
- 在实际的开发中,很多时候还会遇到相对比较复杂的需求,比如产品妹纸或UI妹纸在哪看了个让人兴奋的效果,兴致高昂的来找你,看了之后目的很明确,当
- 这个问题属于非常初级的问题,但是对于初学不知道的人可能会比较头疼。C++ 中函数是不能直接返回一个数组的,但是数组其实就是指针,所以可以让函
- 本文所述实例实现WinForm自定义函数FindControl实现按名称查找控件的功能,在C#程序开发中有一定的实用价值。分享给大家供大家参