【高级编程】网络编程 基于 TCPUDP 协议的 Socket 编程

文章目录

    • IP地址
    • Socket
      • 基于 TCP 协议的 Socket 编程
      • 基于 UDP 协议的 Socket 编程

IP地址

IP地址(Internet Protocol):唯一标识网络上的每一台计算机

IP地址的组成:32位,由4个8位二进制数组成

11000000.10101000.00000001.11001000 ==> 192.168.1.200

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

  • 网络地址:标识计算机或网络设备所在的网段
  • 主机地址:标识特定主机或网络设备
8位 + 24位前8位取值范围
A类网络 主机 主机 主机1~126
B类网络 网络 主机 主机128~191
C类网络 网络 网络 主机192~223
D类用于组播通信224~239
E类用于科研240~255

IP地址的配置和检测

查看IP地址,检测网络是否畅通

  • 查看本机的IP地址:ipconfig

  • 测试网络是否通畅:ping 目标IP地址

DNS域名解析

DNS:Domain Name System,域名系统

网络服务器

通常指在网络环境下,具有较高计算能力,能够提供用户服务功能的计算机

网络服务器 ===> 邮件服务器 Web服务器

  • Microsoft IIS
  • APACHE
  • Apache Tomcat

网络通信协议

为了在网络中不同的计算机之间进行通信而建立的规则、标准或约定的集合

OSI七层网络模型TCP/IP四层概念模型协议
应用层应用层规定了数据的传输格式HTTP FTP TFTP NFS WAIS SMTP
表示层Telnet Rlogin SNMP
会话层SMTP DNS
传输层传输层端口到端口的连接通信TCP UDP
网络层网络层引入一套新的地址来区分不同的广播域ICMP IP ARP RARP AKP UUCP
数据链路层数据链路层定义电信号的分组方式FDDI Ethernet Arpanet PDN SLIP PPP
物理层基于电器特征的高低电压(电信号)高电压代表1 低电压代表0IEEE 802.1A IEEE 802.2到IEEE 802.11

TCP VS UDP

TCPUDP
是否连接面向连接面向非连接
传输可靠性可靠不可靠
速度
在这里插入图片描述在这里插入图片描述

TCP可靠性源于序列号和确认序列号,UDP不能保证数据交付的可靠性

Socket

Socket 是一种网络通信的基础工具,它用于在计算机网络上进行数据传输。简而言之,Socket 提供了应用程序与网络之间的接口,使得应用程序可以通过网络发送和接收数据。

Socket 的底层机制复杂,Java 平台提供了一些简单的 API,可以更简单有效的使用Socket 开发而无需了解底层机制

  • 通信链路的端点就被称为 " 套接字 "(英文名Socket)

  • 是提供给应用程序的接口

Socket 类是 java.net 包的一部分,用于实现基于TCP的网络通信。

java.net包

  • Socket

  • ServerSocket

  • DatagramPacket

  • DatagramSocket

  • InetAddress

基于 TCP 协议的 Socket 编程

基于TCP 协议的 Socket 网络通信:用来实现双向安全连接网络通信

三次握手(建立连接)四次挥手(关闭连接)
A -> B 携带syn数据包A -> B 发送fin包
B -> A 同意连接 发送syn+ackB -> A 发送ack包 进入等待关闭状态
A -> B 再次发送syn数据包B -> A 发送fin包 进入最后确认状态
A -> B 回复ack包 进入超时等待状态 等待结束关闭A B收到ack后立即关闭连接

Socket 通信模型

  • 进行网络通信时,Socket 需要借助数据流来完成数据的传递工作

Socket 网络编程一般可以分成如下步骤进行

0、创建Socket 网络编程模型:客户端/服务器(C/S)

  • 服务器端创建一个 ServerSocket 对象 指定端口号 ServerSocket 负责监听客户端的连接请求。客户端创建一个 Socket 对象 指定服务器的地址和端口号 Socket 负责与服务器建立连接

1、建立连接

  • 服务器端使用 ServerSocketaccept() 方法等待客户端连接。这个方法会阻塞直到一个客户端连接进来

2、打开 Socket 关联的输入输出流

  • 服务器端通过 Socket 对象获取输入输出流(InputStreamOutputStream) 用于接收和发送数据。客户端通过 Socket 对象获取输入输出流 用于与服务器通信

3、数据流中读写信息

  • 使用 InputStreamOutputStream(或者更高层次的 BufferedReaderPrintWriter)进行数据传输 服务器和客户端可以通过这些流进行数据的读取和写入

4、关闭所有的数据流和 Socket

  • 在通信完成后,双方应当关闭流和 socket 连接,以释放资源
// 传递对象信息 序列化
ObjectOutputStream oos = new ObjectOutputStream(...);
oos.writeObject(...);ObjectInputStream ois = new ObjectInputStream(...);
Object = ois.readObject();

举例

使用 java.net 包来创建一个简单的 TCP 客户端-服务器应用程序。

UserServer 代表服务器端,UserClient 代表客户端。

public class UserServer {public static void main(String[] args) {// 假设服务器端口号为 8888System.out.println("---服务器---");try {// 构建服务器ServerSocket serverSocket = new ServerSocket(8888);// 监听客户端发送来的信息 获得socketSocket socket = serverSocket.accept();// 获得字节流InputStream is = socket.getInputStream();// 读取数据StringBuilder sb = new StringBuilder();byte[] buffer = new byte[1024];int bytesRead;while ((bytesRead = is.read(buffer)) != -1) {sb.append(new String(buffer, 0, bytesRead, "UTF-8"));}// 输出消息String msg = sb.toString();System.out.println("收到的消息: " + msg);// 释放资源is.close();socket.close();serverSocket.close();} catch (IOException e) {e.printStackTrace();}}
}
public class UserClient {public static void main(String[] args) {System.out.println("---客户端---");try {// 建立 socket 连接 指定服务器 IP + 端口号Socket socket = new Socket("localhost",8888);// 获得字节流OutputStream os = socket.getOutputStream();os.write("hello TCP!!!".getBytes());// 释放资源os.close();socket.close();mm} catch (IOException e) {e.printStackTrace();}}
}

TCP 对象传递

public class Student implements Serializable {private static final long serialVersionUID = 1L;private String name;private String age;public Student(String name, String age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "Student{name='" + name + "', age='" + age + "'}";}
}public class StudentServer {public static void main(String[] args) {System.out.println("---服务器---");ServerSocket serverSocket = null;Socket socket = null;InputStream is = null;ObjectInputStream ois = null;try {// 构建服务器serverSocket = new ServerSocket(8888);// 监听客户端发送来的信息 获得socketsocket = serverSocket.accept();// 获得字节流is = socket.getInputStream();ois = new ObjectInputStream(is);// 读取 Student 对象Student student = (Student) ois.readObject();System.out.println(student.toString());} catch (IOException | ClassNotFoundException e) {e.printStackTrace();} finally {// 关闭资源......}}
}public class StudentClient {public static void main(String[] args) {System.out.println("---客户端---");Socket socket = null;ObjectOutputStream oos = null;try {// 建立 socket 连接 指定服务器 IP + 端口号socket = new Socket("127.0.0.1", 8888);oos = new ObjectOutputStream(socket.getOutputStream());// 创建并发送 Student 对象oos.writeObject(new Student("张三", "18"));System.out.println("发送成功!");} catch (IOException e) {e.printStackTrace();} finally {// 关闭资源if (oos != null) {try {oos.close();} catch (IOException e) {e.printStackTrace();}}if (socket != null) {try {socket.close();} catch (IOException e) {e.printStackTrace();}}}}
}

多线程处理多请求 实现多客户请求

采用多线程的方式;一个专门负责监听的应用主服务程序;一个专门负责处理请求的线程程序。

public class LoginServer {public static void main(String[] args) {try {System.out.println("\n服务端--------------------");ServerSocket serverSocket = new ServerSocket(8888);Socket socket = null;while (true) {socket = serverSocket.accept();// 创建一个线程来处理登录请求new LoginThread(socket).start();}} catch (Exception e) {e.printStackTrace();}}
}public class LoginThread extends Thread {private Socket socket;public LoginThread(Socket socket) {this.socket = socket;}@Overridepublic void run() {try {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);} finally {try {if (socket != null && !socket.isClosed()) {socket.close();}} catch (IOException ex) {ex.printStackTrace();}}}
}public class LoginClient01 {public static void main(String[] args) {System.out.println("---客户端01---");try {Socket socket = new Socket("127.0.0.1", 8888);OutputStream os = socket.getOutputStream();os.write("用户名:张三,密码:123456".getBytes());os.flush(); // 确保数据已经发送出去socket.close();} catch (IOException e) {e.printStackTrace();}}
}

基于 UDP 协议的 Socket 编程

DatagramSocket:用于发送和接收数据报(UDP数据包)。它提供了用于创建 UDP 套接字并通过其发送和接收数据报的功能。

DatagramPacket:表示要发送或接收的 UDP 数据包。它包含了数据及其目的地地址或来源地址。

基于 UDP 协议的 Socket 网络编程步骤

1、利用 DatagramPacket 对象封装数据包

2、利用 DatagramSocket 发送数据包

3、利用 DatagramSocket 接收数据包

4、利用 DatagramPacket 处理数据包

DatagramSocketsend(DatagramPacket packet) 方法将 DatagramPacket 数据包发送到网络上。DatagramSocketreceive(DatagramPacket packet) 方法从网络中接收数据,并将数据填充到 DatagramPacket 中。

public class UserServer {public static void main(String[] args) {System.out.println("---我是服务端---");DatagramSocket ds = null;DatagramPacket dp = null;Scanner scanner = new Scanner(System.in);try {//接收信息ds = new DatagramSocket(8888);while (true){byte info[] = new byte[1024];//创建数据包 空包dp = new DatagramPacket(info,info.length);//监听ds.receive(dp);//拆包 获得数据String msg = new String(dp.getData(), 0, dp.getLength()).trim();System.out.println("客户端说:"+msg);//发送System.out.print("服务端请输入:");String content = scanner.next();//获得上个数据包的发送地址SocketAddress sa = dp.getSocketAddress();//封装数据包dp = new DatagramPacket(content.getBytes(),content.getBytes().length,sa);ds.send(dp);}} catch (Exception e) {e.printStackTrace();}}
}public class UserClient {public static void main(String[] args) {//发送信息Scanner scanner = new Scanner(System.in);System.out.println("---我是客户端---");DatagramPacket dp = null;DatagramSocket ds = null;try {while(true){System.out.print("客户端请输入:");String msg = scanner.next();//封装数据包 字节数组  字节数组长度  地址对象InetAddress 端口号dp = new DatagramPacket(msg.getBytes() ,msg.getBytes().length,InetAddress.getByName("127.0.0.1"),8888);//创建发送接收对象ds = new DatagramSocket();//发送数据包ds.send(dp);//接收byte info[] = new byte[1024];//创建数据包 空包dp = new DatagramPacket(info,info.length);//监听ds.receive(dp);//拆包 获得数据String content = new String(dp.getData(), 0, dp.getLength()).trim();System.out.println("服务器说:"+ content);}} catch (Exception e) {e.printStackTrace();}finally {ds.close();}}
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++ 赋值运算符重载

个人主页:Jason_from_China-CSDN博客 所属栏目:C系统性学习_Jason_from_China的博客-CSDN博客 所属栏目:C知识点的补充_Jason_from_China的博客-CSDN博客 概念概述 赋值运算符重载的特点: 成员函数:赋值运算符重载必须…

IPv6(三)

文章目录 IPv6报文 IPv6报文 IPv6基本报头有8个字段,固定大小为40字节,,每个IPv6数据都必须包含报头,基本报头提供报文转发的基本信息,会被转发路径上面的所有路由器解析 IPv6报头长度为40字节Version:版本…

leetcode21. 合并两个有序链表

思路: 用一个新链表来表示合并后的有序链表, 每次比较两个链表,将较小的那个结点存储至新链表中 # Definition for singly-linked list. # class ListNode(object): # def __init__(self, val0, nextNone): # self.val val # …

sheng的学习笔记-AI-归纳逻辑程序设计(ILP)

AI目录:sheng的学习笔记-AI目录-CSDN博客 规则学习(rule learning): sheng的学习笔记-AI-规则学习(rule learning)-CSDN博客 一阶规则学习: sheng的学习笔记-AI-FOIL(First-Order Inductive Learner)-CSD…

什么是 SSL 代理?

您可能已经对代理有所了解,例如移动代理、住宅代理和数据中心代理之间的区别。但是 SSL 代理到底是什么?它与其他类型的代理相比有何不同? 让我们分析一下,看看 SSL 代理有何特殊之处。 1.什么是 SSL/HTTPS 代理? SS…

《高等代数》分块矩阵(应用)

说明:此文章用于本人复习巩固,如果也能帮助到大家那就更加有意义了。 注:1)利用分块矩阵的相关公式进行证明

[PTA]7-5 求组合数

[PTA]7-5 求组合数 输入格式: 输入在一行中给出两个正整数m和n&#xff08;m≤n&#xff09;&#xff0c;以空格分隔。 输出格式: 按照格式“result 组合数计算结果”输出。题目保证结果在double类型范围内。 输入样例: 2 7 输出样例: result 21 代码 #include<stdio…

【Linux进程控制】进程程序替换

目录 进程程序替换 替换函数 看现象 替换原理 多进程替换 exec*函数使用&#xff08;部分&#xff09;&#xff0c;并且认识函数参数的含义 1.execl 2.execv 3.execvp 4.execvpe execlp 和execlpe 替换函数总结 进程程序替换 替换函数 有六种以exec开头的函数&am…

unity将多层嵌套的结构体与json字符串相互转化

定义多个结构体&#xff0c;将结构体内容输入到最终的JObject中&#xff0c;然后将其转为字符串打印出来&#xff0c;即可。 代码内容如下&#xff1a; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using UnityEngine;public class Test : MonoBehaviour {private Ap…

3.接口测试的基础/接口关联(Jmeter工具/场景一:我一个人负责所有的接口,项目规模不大)

一、Jmeter接口测试实战 1.场景一&#xff1a;我一个人负责所有的接口&#xff1a;项目规模不大 http:80 https:443 接口文档一般是开发给的&#xff0c;如果没有那就需要抓包。 请求默认值&#xff1a; 2.请求&#xff1a; 请求方式:get,post 请求路径 请求参数 查询字符串参数…

二分算法——优选算法

个人主页&#xff1a;敲上瘾-CSDN博客 个人专栏&#xff1a;游戏、数据结构、c语言基础、c学习、算法 本章我们来学习的是二分查找算法&#xff0c;二分算法的应用非常广泛&#xff0c;不仅限于数组查找&#xff0c;还可以用于解决各种搜索问题、查找极值问题等。在数据结构和算…

web - JavaScript

JavaScript 1&#xff0c;JavaScript简介 JavaScript 是一门跨平台、面向对象的脚本语言&#xff0c;而Java语言也是跨平台的、面向对象的语言&#xff0c;只不过Java是编译语言&#xff0c;是需要编译成字节码文件才能运行的&#xff1b;JavaScript是脚本语言&#xff0c;不…

【Java版】云HIS系统源码

云HIS系统介绍 云HIS系统是一款满足基层医疗机构各类业务需要的健康云产品。该产品能帮助基层医疗机构完成日常各类业务&#xff0c;提供病患挂号支持、病患问诊、电子病历、开药发药、会员管理、统计查询、医生站和护士站等一系列常规功能&#xff0c;还能与公卫、PACS等各类…

蓝星多面体foc旋钮键盘复刻问题详解

介绍&#xff1a; 本教程是针对立创开源项目 承载我所有幻想的键盘 - 立创开源硬件平台 作者是 蓝星多面体 这里我总结一下我复刻过程中的一些问题 一 <<编译环境怎么搭建&#xff1f;>> 第一步 安装vscode 下载vscode &#xff08;可以在各大应用平台…

【HarmonyOS 】编译报错:Install Failed: error: failed to install bundle

此问题是由于支付宝sdk兼容性造成的&#xff0c;目前只能删除支付宝sdk依赖&#xff0c;如下图所示操作&#xff0c;删除后需要点右上角的 Sync Now&#xff0c;并等待 Sync 结束 删除后还需要点右上角的 Sync Now&#xff0c;并等待 Sync 结束 uniapp解决方案&#xff1a; htt…

mysql5.7小版本升级

最近因为mysql漏洞问题需要升级版本 目标&#xff1a;5.7.17升级到最新的5.7.44 提前准备&#xff1a;必须 MySQL :: Download MySQL Community Server (Archived Versions) 下载最新的5.7版本5.7.44&#xff0c;下载后&#xff0c;解压备用 ​ 方案1&#xff1a;卸载原有…

[C语言]第九节 函数一基础知识到高级技巧的全景探索

目录 9.1 函数的概念 9.2 库函数 9.2.1 标准库与库函数 示例&#xff1a;常见库函数 9.2.2 标准库与头文件的关系 参考资料和学习工具 如何使用库函数 ​编辑 9.3 ⾃定义函数 9.3.1 函数的语法形式 9.3.2函数的举例 9.4 实参与形参 9.4.1 什么是实参&#xff1f; 9…

求Huffman树及其matlab程序详解

#################本文为学习《图论算法及其MATLAB实现》的学习笔记################# 算法用途 求Haffman树 算法思想 根据定理4.17,给出求Huffman树的算法步骤如下: ①对给出的所要求的叶子顶点的权进行从小到大排序,写出的权重向量 ; ②根据定理4.17,写出兄弟的权重分别为…

《Pyramid Vision Transformer》论文笔记

原文笔记 What 为了解决VIT在视觉任务上的局限性并且探究Transformer模型在视觉任务上的应用&#xff0c;这项工作提出了一种纯 Transformer 主干&#xff0c;称为 Pyramid Vision Transformer (PVT)&#xff0c;它可以作为 CNN 主干在许多下游任务中的替代方案&#xff0c;包…

全网最适合入门的面向对象编程教程:50 Python函数方法与接口-接口和抽象基类

全网最适合入门的面向对象编程教程&#xff1a;50 Python 函数方法与接口-接口和抽象基类 摘要&#xff1a; 在 Python 中&#xff0c;接口和抽象基类&#xff08;Abstract Base Classes, ABCs&#xff09;都用于定义类的结构和强制子类实现特定的方法&#xff0c;Python 没有…