网络编程:掌握TCP Socket和UDP Socket

IP地址:

两台计算机通信,双方都必须有IP地址。

IPV4地址有32位,由四个8位二进制组成,因为不好记所以我们把二进制转化为十进制,比如192.168.0.20,这称为点分十进制。

IPV6有128位,由8个16位的无符号整数组成,每个整数用4个十六进制数表示,这些数之间用冒号(:)分开。

IP地址的分类:

IP地址 = 网络地址 +主机地址

网络地址决定网络数

主机地址决定了一个网络中可以存在的计算机最大数量

A类IP地址:前八位表示网络地址,取值范围1-126

B类IP地址:前十六位表示网络地址,取值范围128-191

C类IP地址:前三组表示网络地址,取值范围192-223

D类IP地址:不分网络地址和主机地址, 用于多播(Multicast)。多播通信是一种将数据包发送到多个特定接收者的方式,而不是广播给网络上的所有设备。常用于视频会议、流媒体传输等应用。

特殊的IP地址:

0.0.0.0表示主机

127.0.0.1表示本机回环地址,通常用于本机ping此地址来检查TCP/IP协议安装是否正确

255.255.255.255表示当前子网

IP地址的配置和检测:

查看本机的IP地址:
ipconfig

测试网络是否通畅:

ping  目标IP地址

DNS域名解析(域名系统):

访问网站时,为什么输入网址而不是IP地址?

因为ip地址都是数字,人们输入的时候太枯燥,所以需要一个系统将一个名称映射为它的IP地址,DNS域名解析系统。

网络通信协议:

TCP/IP:五层

首先应用层准备好要发送的数据,然后给了传输层。

传输层的主要作用就是为发送端和接收端提供可靠的连接服务,传输层将数据处理完后就给了网络层。

网络层的功能就是管理网络,其中一个核心的功能就是路径的选择(路由选择),从发送端到接收端有很多条路,网络层就负责管理下一步数据应该到哪个路由器。选择好了路径之后,数据就来到了数据链路层,

数据链路层就是负责将数据从一个路由器送到另一个路由器。然后就是物理层了,可以简单的理解,

物理层就是网线一类的最基础的设备。

TCP协议:

传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议

例子:

发货之前工作人员首先得要确认一下路是不是通吧,比如现在是过年,物流全部停运不就是路不通吗,那还发什么货呀。要是没什么问题,物流全部正常运作就发货呗。手机到达小明家后,小明先拆开看看手机在运输途中有没有损坏,有损坏就联系客服处理,没问题就确认收货。再回到上面的定义中,面向连接指的是先建立连接再发送数据,也就是先确认路可以走得通再发货。可靠就是如果货物在运输过程中有损坏或者丢失就让京东重新发货,确保小明收到的手机是没有任何问题的。基于字节流的意思就是比如小明买了手机又买了手机配件,分开发货,几件物品不是在一个包裹里,一个一个发。在这个例子中,京东的工作人员和小明充当了TCP协议的角色,他们两个共同确保了货物的完整性。

总结:确定是通的,如果丢失就重新再发,数据是以字节流的方式传送的。

建立连接 接收数据 发送数据

三次握手四次挥手:

三次握手:

A:是B吗?我要跟你通信,听得到我说话吗?

B:可以通信,你听得到我说话吗?

A:我也听得到。

之所以挥手三次是为了防止丢包的链接被服务端等待

四次挥手:

A:我困了,先不聊了吧

B:还有几件事,说完我们就睡觉…… ……(说完之后)

B:好了,说完了,我挂线了

A:好,你挂吧

B挂断电话

A说完之后就直接睡觉了,不知道电话挂没挂断,在几分钟后听到手机没有声音传来了,即使不用睁眼也知道B挂断了

四次挥手如图:

之所以还需要最后的ack发送后还需要等待,是因为服务端需要收到后才可以断开连接,所有如果ack丢失的话服务端可以再给客户端发一次。

UDP协议:

面向无连接的

TCP和Socket:

TCP通信协议是一种可靠的网络协议,它在通信的两端各建立一个Socket对象,通信之前要保证连接已建立。

通过Socket产生I/O流来进行网络通信。

客户端:

public class Socket01 {public static void main(String[] args) {Socket socket =null;OutputStream os =null;//客户端try {socket = new Socket("127.0.0.1",8888);//创建输出流os = socket.getOutputStream();os.write("chenmengyu Hello".getBytes());} catch (Exception e) {e.printStackTrace();}finally {try {os.close();socket.close();} catch (IOException e) {e.printStackTrace();}}}
}

服务器端:

首先要运行接收端,不然发送端连接不上就不会发送数据

Socket s = ss.accept();会一直等待发送端的连接,死等

第一种:循环的接收

不需要字符串了,但是缺点是只能够传输字母,不能传中文

public static void main(String[] args) {ServerSocket serverSocket = null;Socket socket = null;InputStream inputStream =null;try {//创建serverSocketserverSocket = new ServerSocket(8888);//监听客户端获取socket对象socket = serverSocket.accept();//获取输出流inputStream = socket.getInputStream();int read;while ((read=inputStream.read())!=-1){System.out.print((char)read);}} catch (IOException e) {e.printStackTrace();}finally {try {serverSocket.close();socket.close();inputStream.close();} catch (IOException e) {e.printStackTrace();}}}

第二种数组接收:

byte b[] = new byte[100];

String str = new String(b);

用byte数组接收再转成字符串输出

public class Socket02 {public static void main(String[] args) {ServerSocket serverSocket = null;Socket socket = null;InputStream inputStream =null;try {//创建serverSocketserverSocket = new ServerSocket(8888);//监听客户端获取socket对象socket = serverSocket.accept();//获取输出流inputStream = socket.getInputStream();byte b[] = new byte[100];inputStream.read(b);String str = new String(b);System.out.println(str);} catch (IOException e) {e.printStackTrace();}finally {try {serverSocket.close();socket.close();inputStream.close();} catch (IOException e) {e.printStackTrace();}}}
}

TCP传输序列化对象:

客户端:
public class ObjSocket01 {public static void main(String[] args) {//客户端Socket socket = null;OutputStream os = null;ObjectOutputStream objectOutputStream = null;try {socket = new Socket("127.0.0.1",8888);os = socket.getOutputStream();objectOutputStream = new ObjectOutputStream(os);objectOutputStream.writeObject(new Student("陈梦雨",21));} catch (IOException e) {throw new RuntimeException(e);}finally {try {socket.close();os.close();objectOutputStream.close();} catch (IOException e) {throw new RuntimeException(e);}}}
}

服务器端:

readObject()方法的作用是从输入流中读取一个序列化的对象,并将其转换为Java对象。它会返回一个Object类型,通常需要进行类型转换

public class ObjSocket02 {public static void main(String[] args) {ServerSocket socket = null;InputStream inputStream = null;ObjectInputStream ois = null;try {socket = new ServerSocket(8888);//监听客户端Socket socket1 = socket.accept();//获取输入流inputStream= socket1.getInputStream();//创建一个反序列化对象,并且把输入流当参数放进去ois = new ObjectInputStream(inputStream);//readObject()方法则从流中读取对象并将其转换为Student类型的实例Student stu= (Student)ois.readObject();System.out.println(stu.toString());} catch (Exception e) {e.printStackTrace();}}
}

例题:多客户端用户登录:

TCP的Socket和多线程联动

需要创建子线程的是服务端,它创建多个子线程去处理客户端发送的东西

不使用多线程:

就是用while(true)使服务端一直等一直监听

服务器端:

package QuestionPpt02;import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;public class demo01 {public static void main(String[] args) {ServerSocket serverSocket = null;Socket socket = null;//服务器端try {serverSocket = new ServerSocket(8888);socket = new Socket();while(true){//监听socket = serverSocket.accept();InputStream is = socket.getInputStream();byte b[] = new byte[50];is.read(b);String msg = new String(b);System.out.println(msg);}} catch (IOException e) {throw new RuntimeException(e);}}
}

客户端:


public class demoCelint01 {public static void main(String[] args){//客户端1System.out.println("客户端01————————————");try {Socket socket = new Socket("127.0.0.1",8888);OutputStream os = socket.getOutputStream();os.write("用户名:张三".getBytes());os.close();socket.close();} catch (IOException e) {throw new RuntimeException(e);}}
}
使用多线程:

它的客户端和上面一样

服务端主线程:

通过构造方法传入监听过来的socket对象,然后进入子线程

package QuestionPpt02;import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;public class demo02 {public static void main(String[] args) {ServerSocket serverSocket = null;Socket socket = null;//服务器端try {serverSocket = new ServerSocket(8888);socket = new Socket();while(true){//监听socket = serverSocket.accept();//一旦有用户来就创建一个子线程ThreadTest threadTest = new ThreadTest(socket);threadTest.start();}} catch (IOException e) {throw new RuntimeException(e);}}
}

服务端子线程:

package QuestionPpt02;import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;public class ThreadTest extends Thread{private Socket socket;public  ThreadTest(Socket socket){this.socket = socket;}//服务端创建子线程@Overridepublic  void run(){try {InputStream is = null;is = socket.getInputStream();byte b[] = new byte[50];is.read(b);String msg = new String(b);System.out.println(msg);} catch (IOException e) {e.printStackTrace();}}
}

UDP和socket:

DatagramSocket:用来发送和接收数据包

DatagramPacket:用来装包和拆包

dp.getData()拆包

ds.send(dp);发送包

基于UDP协议的sokect实现

发送端(客户端):

DatagramPacket的构造方法最常用的,接收(发送内容的比特数组,数组长度,地址对象,端口号)

InetAddress.getByName("127.0.0.1")是一个地址对象,反正这里不能直接填地址

public class LoginCelint {//客户端public static void main(String[] args) {System.out.println("我是客户端---------------");//发送信息Scanner scanner = new Scanner(System.in);DatagramPacket dp = null;DatagramSocket ds = null;try {System.out.print("客户端请输入:");String msg = scanner.nextLine();dp = new DatagramPacket(msg.getBytes(),msg.getBytes().length,InetAddress.getByName("127.0.0.1"),8888);ds = new DatagramSocket();ds.send(dp);} catch (Exception e) {e.printStackTrace();}finally {ds.close();}}
}

接收端(服务器):
  1. 一定要先运行接收方, 在 UDP 通信中,接收方需要在指定的端口上监听和等待数据包

DatagramPacket的构造方法(byte数组,数组长度)

  1. String msg = new String(dp.getData());先 获取DatagramPacket中存储的数据的字节数组。再转成String
public class LoginServer {//服务器public static void main(String[] args) {System.out.println("我是服务端——————————");Scanner scanner = new Scanner(System.in);DatagramPacket dp = null;DatagramSocket ds = null;try {ds = new DatagramSocket(8888);byte b[] = new byte[100];dp = new DatagramPacket(b, b.length);//等待接收ds.receive(dp);//拆包String msg = new String(dp.getData());System.out.println("客户端对我说:" + msg);} catch (Exception e) {e.printStackTrace();}finally {ds.close();}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/144665.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Python精选200Tips:151-155

实战项目 P151--气象数据爬取技术栈:数据爬虫P152--求解数独问题技术栈:代码逻辑+回溯法P153--疾病传播模型的100天模拟技术栈:SIR 模型(易感-感染-恢复模型)P154--复杂函数的最值求解技术栈:粒子群优化算法P155-- 评论情感分析技术栈:snownlp和jieba的应用运行系统:ma…

Ubuntu 64系统信息查看

一、查看系统基本信息 uname -a 显示系统内核名称、主机名、内核版本号、发布日期等信息。 Linux ubuntu 5.4.0-150-generic #167~18.04.1-Ubuntu SMP Wed May 24 00:51:42 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux 内核版本:这是一个基于 Linux 的 Ubuntu 系…

NC65使用UAP客开主子单据以及NC65常见的开发技术(超级详细附带图和源码)

NC65使用UAP客开主子单据以及NC65单据相关的开发技术(超级详细附带图和源码) 本篇主要讲述使用UAP开发工具客开主子单据包括:创建项目发布、创建发布元数据、生成主子单据、以及相关报错和打补丁。在单据相关技术主要包括:增加空按…

力扣 42.接雨水

文章目录 题目介绍解法 题目介绍 解法 法一:通过计算每个位置 i 能够捕获的雨水量,然后将他们相加。 具体做法是:创建两个数组:preMax 和 sufMax 分别用来存储每个位置左边和右边的最大高度,则每个位置 i 可以捕获的…

Snowflake的“AI + 数据” 模式,如何颠覆传统数据处理!

Snowflake的“AI 数据” 模式,如何颠覆传统数据处理! 前言Snowflake的“AI 数据” 模式 前言 Snowflake是一种基于云的数据平台,拥有着强大的能力,能够帮助我们存储、管理和分析海量的数据,就像是我们的得力助手&am…

骨传导耳机哪个牌子好?盘点口碑最好的5款骨传导耳机!

在快节奏的现代生活中,耳机成为了我们与外界沟通的重要桥梁,无论是在通勤路上、健身锻炼,还是在工作学习中,耳机都扮演着不可或缺的角色。而在众多耳机类型中,骨传导耳机以其独特的声音传导方式和健康舒适的佩戴体验&a…

【Python报错已解决】 OSError: [Errno 22] Invalid argument

🎬 鸽芷咕:个人主页 🔥 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想,就是为了理想的生活! 专栏介绍 在软件开发和日常使用中,BUG是不可避免的。本专栏致力于为广大开发者和技术爱好者提供一个关于BUG解决的经…

灯塔:JavaScript

Web标准也称为网页标准,由一系列的标准组成,大部分由W3C(World Wide Web Consortium,万维网联盟)负责制定。 三个组成部分: HTML:负责网页的基本结构(页面元素和内容)。 CSS&…

作品集生成链接或二维码:设计师求职

在竞争激烈的设计行业,如何让自己的作品集脱颖而出,成为打开理想职业大门的关键钥匙?今天,我们就来聊聊将作品集生成链接或二维码这一强大功能,它正逐渐成为设计师们求职申请和作品展示的新利器。 一、传统作品集的困境…

SwiftData 共享数据库在 App 中的改变无法被 Widgets 感知的原因和解决

0. 问题现象 我们 watchOS 中的 App 和 Widgets 共享同一个 SwiftData 底层数据库,但是在 App 中对数据库所做的更改并不能被 Widgets 所感知。换句话说,App 更新了数据但在 Widgets 中却看不到。 如上图所示:我们的 App 在切换至后台之前会…

Mysql事务相关

什么是事务 事务是指是程序中一系列严密的逻辑操作,而且所有操作必须全部成功完成,否则在每个操作中所作的所有更改都会被撤消。可以通俗理解为:就是把多件事情当做一件事情来处理,好比大家同在一条船上,要活一起活&a…

置换排列的数学表达与Benes网络

摘要 本文主要讨论如何使用Benes网络完成排列的置换操作,介绍Benes网络的构造,以及具体的路由方式。 置换排列 这里的排列指一个n个不同元素的序列,不同的顺序代表不同的排列。比如 [ 1 , 2 , 3 , 4 ] [1,2,3,4] [1,2,3,4]和 [ 2 , 1 , 4 …

优青博导团队提供生信分析整体解决方案丨组学技术服务、表观组分析、互作组分析、遗传转化实验、单细胞检测与生物医学

平民价格给您最优的技术服务——生物信息技术分析就找汇智生物 业务领域: 组学技术服务 、表观组分析、互作组分析、遗传转化实验、单细胞检测与生物医学 合作免费提供: 博导团队免费指导实验、免费解读实验结果、实验整体打包服务、免费论文润色 生物…

TAPD7.0焕新升级!助力企业数字化敏捷研发提效

近日,TAPD的7.0升级版本,不仅外观、引擎、协作焕新升级,大型产品规模化,敏捷‍‍‍‍‍‍‍‍更跨组织/地域,研发协作小团队更轻便。 腾讯TAPD7.0焕新升级! “外观”升级 导航革新:重塑导航栏…

windows10部署ChatTTS+Apifox调用

1 文件准备 准备好如下图所示的文件 2 修改ChatTTS_Win\ChatTTS\uilib\cfg.py 如下图所示,注释第34行,增加 WEB_ADDRESS 0.0.0.0:9998确保局域网内的其他设备也可以请求该服务。 3 启动服务 4 发送post请求 对应的请求内容如下: bash代…

字节推音乐生成神器 Seed-Music 支持多样化输入和精确控制

Seed-Music,字节跳动的最新音乐创作神器,能通过文字、音频等多种方式轻松生成音乐,仿佛拥有魔法般的魔力。它巧妙地融合了自回归语言模型与扩散模型,不仅确保了音乐作品的高品质,还赋予了用户对音乐细节的精准掌控能力…

【2025】中医药健康管理小程序(安卓原生开发+用户+管理员)

博主介绍: ✌我是阿龙,一名专注于Java技术领域的程序员,全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师,我在计算机毕业设计开发方面积累了丰富的经验。同时,我也是掘金、华为云、阿里云、InfoQ等平台…

电商商品详情API接口对电商跨境电商企业运营的好处

为了获取更大利益,电商商家经常需要使用价格,ERP接口系统。价格接口对电商商家有多方面的好处,主要体现在以下几个方面: 1、价格接口系统可以帮助品牌和商家实现更加科学和精准的定价策略。通过实时获取多个主流电商平台&#xf…

基于SpringBoot的智能排课系统设计与实现

文未可获取一份本项目的java源码和数据库参考。 (一)选题来源与背景 高校的每学期伊始,排课是教务处工作中的重中之重。安排合理无资源冲突(教师、教室和设备等教学资源)的课表是教务工作必须面临的问题。传统的人工…

【Python】练习:控制语句(二)第1关

第1关:分支结构基础实训 第一题第二题第三题第四题(※)第五题(※)第六题第七题 第一题 #第一题 for temp in [-280, -100, 0, 20, 120, 200]:#请在下面编写代码# ********** Begin ********** #if temp>-273.15:F9/…