Java之TCP和UDP进行网络编程

news2024/11/20 7:19:31

目录

一.网络编程

1.1网络编程的作用

1.2网络编程的基本概念   

1.3网络编程的实现

二.UDP网络编程

2.1UDP数据报套的初步了解

2.2Java数据报套接字通信模型 

2.3Java编程实现UDP通信

三.TCP网络编程

 3.1TCP流套接字api

3.2TCP通信代码实现

3.2.1短连接实现代码

3.2.2长连接实现代码

四.总结


🎁个人主页:tq02的博客_CSDN博客-C语言,Java,Java数据结构领域博主
🎥 本文由 tq02 原创,首发于 CSDN🙉
🎄 本章讲解内容:TCP和UDP的编程讲解

🎥学习专栏:  C语言         JavaSE       MySQL基础     多线程学习

一.网络编程

1.1网络编程的作用

网络编程:指网络上的主机,通过不同的进程,以编程的方式实现网络通信(或称为网络数据传输)

换句话说:通过网络编程可以进行网络资源的数据传输,例如:腾讯视频观看网络电视

1.2网络编程的基本概念   

在一次网络数据传输时:

        发送端:数据的发送方进程,称为发送端。发送端主机即网络通信中的源主机。

        接收端:数据的接收方进程,称为接收端。接收端主机即网络通信中的目的主机。

        收发端:发送端和接收端两端,也简称为收发端。

注意:发送端和接收端只是相对的,只是一次网络数据传输产生数据流向后的概念

网络数据传输的请求和响应

一般而言,获取一个网络资源需要涉及到两次的网络数据传输:

  1. 请求数据的发送   -----客户端
  2. 响应数据的发送   ------服务端

注:客户端将资源保存在服务端,例如设置密码,将密码保存在服务端,这样即使换台客户端也能登陆。

1.3网络编程的实现

        网络编程的实现是通过Socket套接字,由系统供用于网络通信的技术,将传输层协议划主要划分为两类:TCP协议和UDP协议。因此TCP和UDP是网络资源数据传输的重要协议

重点:牢记Socket套接字。TCP和UDP都有其api,通过这个可以进行网络编程。

二.UDP网络编程

2.1UDP数据报套的初步了解

        在Java当中,实现UDP协议的通信的类是-----DatagramSocket(Socket对象),DatagramPacket(udp数据报)

  • DatagramPacket(udp数据报):将需要的传输数据写入其中,传输后也需要该类接收数据。
  • DatagramSocket(Socket对象):发送和接收udp数据报。

2.2Java数据报套接字通信模型 

         java中使用UDP协议通信,主要基于 DatagramSocket 类来创建数据报套接字,并使用

DatagramPacket 作为发送或接收的 UDP 数据报。对于一次发送及接收 UDP 数据报的流程如下:

  1. 发送端:使用DatagramPacket类构造发送的内容,由DatagramSocket发送出去。
  2. 接收端:使用DatagramPacket类保存接收的数据,由DatagramSocket接收该类。

注:在实际情况下,服务器需要提供多个客户端的请求处理及响应。

流程图如下:


2.3Java编程实现UDP通信

        在编程之前,我们先要了解两个类---- DatagramPacket和DatagramSocket。

注:服务器相当于家,客户端相当于你,当你想回家时,我们需要得到服务器的地址(IP地址),门牌号(端口号)

(1)DatagramPacket

构造方法

构造方法方法说明
DatagramPacket(byte[]
buf, int length)
接收数据报 ,接收的数据保存在字节数组(第一个参数buf )中,接收指定长度
(第二个参数length)
DatagramPacket(byte[]
buf, int offset, int length,
SocketAddress address)
发送数据报 ,发送的数据为字节 数组(第一个参数buf )中,从 0 到指定长度
(第二个参数 length)。 address 指定目的主机的 IP 和端口号

方法:

方法名方法说明
InetAddress
getAddress()
从接收的数据报中,获取发送端主机 IP 地址;或从发送的数据报中,获取接收端主机IP 地址
int getPort()
从接收的数据报中,获取发送端主机的端口号;或从发送的数据报中,获取接收端主机端口号
byte[] getData()
获取数据报中的数据

(2)DatagramSocket

构造方法:

构造方法方法说明
DatagramSocket()
创建一个 UDP 数据报套接字的 Socket ,绑定到本机任意一个随机端口
(一般用于客户端)
DatagramSocket(int
port)
创建一个 UDP 数据报套接字的 Socket ,绑定到本机指定的端口(一般用
于服务端)
方法:
方法解析
void receive(DatagramPacket p)
从此套接字接收数据报(如果没有接收到数据报,该方法会阻塞等待)
void send(DatagramPacketp)
从此套接字发送数据报包(不会阻塞等待,直接发送)
void close()
关闭此数据报套接字

我们这以自己的地址为例子,环回IP。

客户端代码:

package network;

import java.io.IOException;
import java.net.*;
import java.util.Scanner;

public class UdpEchoClient {
    private DatagramSocket socket = null;
    private String serverIp;
    private int serverPort;

    // 服务器的 ip 和 服务器的端口.
    public UdpEchoClient(String ip, int port) throws SocketException {
        serverIp = ip;
        serverPort = port;
        // 这个 new 操作, 就不再指定端口了. 让系统自动分配一个空闲端口.
        socket = new DatagramSocket();
    }

    // 让这个客户端反复的从控制台读取用户输入的内容. 把这个内容构造成 UDP 请求, 发给服务器. 再读取服务器返回的 UDP 响应
    // 最终再显示在客户端的屏幕上.
    public void start() throws IOException {
        Scanner scanner = new Scanner(System.in);
        System.out.println("客户端启动!");
        while (true) {
            // 1. 从控制台读取用户输入的内容
            System.out.print("-> "); // 命令提示符, 提示用户要输入字符串.
            String request = scanner.next();
            // 2. 构造请求对象, 并发给服务器.
            DatagramPacket requestPacket = new DatagramPacket(request.getBytes(), request.getBytes().length,
                    InetAddress.getByName(serverIp), serverPort);
            socket.send(requestPacket);
            // 3. 读取服务器的响应, 并解析出响应内容.
            DatagramPacket responsePacket = new DatagramPacket(new byte[4096], 4096);
            socket.receive(responsePacket);
            String response = new String(responsePacket.getData(), 0, responsePacket.getLength());
            // 4. 显示到屏幕上.
            System.out.println(response);
        }
    }

    public static void main(String[] args) throws IOException {
                                                    //服务器ip与端口
        UdpEchoClient client = new UdpEchoClient("127.0.0.1", 9090);
        client.start();
    }
}

服务器代码:

package network;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

// UDP 的 回显服务器.
// 客户端发的请求是啥, 服务器返回的响应就是啥.
public class UdpEchoServer {
    private DatagramSocket socket = null;

    // 参数是服务器要绑定的端口
    public UdpEchoServer(int port) throws SocketException {
        socket = new DatagramSocket(port);
    }

    // 使用这个方法启动服务器.
    public void start() throws IOException {
        System.out.println("服务器启动!");
        while (true) {
            // 反复的, 长期的执行针对客户端请求处理的逻辑.
            // 一个服务器, 运行过程中, 要做的事情, 主要是三个核心环节.
            // 1. 读取请求, 并解析
            DatagramPacket requestPacket = new DatagramPacket(new byte[4096], 4096);
            socket.receive(requestPacket);
            //    这样的转字符串的前提是, 后续客户端发的数据就是一个文本的字符串.
            String request = new String(requestPacket.getData(), 0, requestPacket.getLength());
            // 2. 根据请求, 计算出响应
            String response = process(request);
            // 3. 把响应写回给客户端
            //    此时需要告知网卡, 要发的内容是啥, 要发给谁.
            DatagramPacket responsePacket = new DatagramPacket(response.getBytes(), response.getBytes().length,
                    requestPacket.getSocketAddress());
            socket.send(responsePacket);
            // 记录日志, 方便观察程序执行效果.
            System.out.printf("[%s:%d] req: %s, resp: %s\n", requestPacket.getAddress().toString(), requestPacket.getPort(),
                    request, response);
        }
    }

    // 根据请求计算响应. 由于是回显程序, 响应内容和请求完全一样.
    public String process(String request) {
        return request;
    }

    public static void main(String[] args) throws IOException {
        UdpEchoServer server = new UdpEchoServer(9090);
        server.start();
    }
}

三.TCP网络编程

 3.1TCP流套接字api

        如果想实现TCP的通信,我们需要使用到ServerSocket和Socket。

注意:TCP传输数据,是根据流操作,因此我们需要使用IO流操作

(一)ServerSocket

  • ServerSocket:创建TCP服务端的Socket的API,服务器端通常用于监听指定的端口并等待客户端的连接请求

        构造方法:

构造方法方法说明
ServerSocket(int port)
创建一个服务端流套接字 Socket ,并绑定到指定端口

        方法:

方法方法说明
Socket  accept()
监听指定端口(创建时绑定的端口),有客户端连接后,返回一个服务端 Socket 对象,并基于该Socket 建立与客户端的连接,否则阻塞等待
close()
关闭此套接字

(二)Socket

  • Scoket:用于客户端,服务端中接收到客户端建立连接(accept方法)的请求后,返回的服务端Socket

注:socket通常是一个对网络通信进行抽象的对象,通过它可以实现客户端和服务器之间的数据传输。

构造方法:

构造方法方法说明
Socket(String host, int port)
创建一个客户端流套接字 Socket ,并与对应 IP 的主机上,对应端口的进程建立连接

方法:

方法名方法说明
InetAddress getInetAddress()
返回套接字所连接的地址
InputStream getInputStream()
返回此套接字的输入流
OutputStream getOutputStream()
返回此套接字的输出流

3.2TCP通信代码实现

        TCP代码实现通信,需要先建立连接,而确认什么时候关闭,却可以分为2种----短连接和长连接!
  1. 短连接:每次接收到数据并返回响应后,都关闭连接,即是短连接。也就是说,短连接只能一次收发数据。
  2. 长连接:不关闭连接,一直保持连接状态,双方不停的收发数据,即是长连接。也就是说,长连接可以多次收发数据。

长、短连接区别:

  1. 建立连接、关闭连接的耗时:短连接每次请求、响应都需要建立连接,关闭连接;而长连接只需要 第一次建立连接,之后的请求、响应都可以直接传输。相对来说建立连接,关闭连接也是要耗时 的,长连接效率更高。
  2. 主动发送请求不同:短连接一般是客户端主动向服务端发送请求;而长连接可以是客户端主动发送请求,也可以是服务端主动发。
  3. 两者的使用场景有不同:短连接适用于客户端请求频率不高的场景,如浏览网页等。长连接适用于 客户端与服务端通信频繁的场景,如聊天室,实时游戏等。

3.2.1短连接实现代码

        短连接,则是一发一收,客户端发送请求,服务器接收请求,只有请求,没有回应。

服务端:

package org.example.tcp.demo1;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class TcpServer {
    //服务器socket要绑定固定的端口
    private static final int PORT = 8888;
    public static void main(String[] args) throws IOException {
        // 1.创建一个服务端ServerSocket,用于收发TCP报文
        ServerSocket server = new ServerSocket(PORT);
        // 不停的等待客户端连接
        while(true) {
            System.out.println("---------------------------------");
            System.out.println("等待客户端建立TCP连接...");
            // 2.等待客户端连接,注意该方法为阻塞方法
            Socket client = server.accept();
            System.out.printf("客户端IP:%s%n", client.getInetAddress().getHostAddress());
            System.out.printf("客户端端口号:%s%n", client.getPort());
            // 5.接收客户端的数据,需要从客户端Socket中的输入流获取
            System.out.println("接收到客户端请求:");
            InputStream is = client.getInputStream();
            // 为了方便获取字符串内容,可以将以上字节流包装为字符流
            BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
            String line;
            // 一直读取到流结束:TCP是基于流的数据传输,一定要客户端关闭Socket输出流才表示服
务端接收IO输入流结束
            while ((line = br.readLine()) != null) {
                System.out.println(line);
           }
            // 6.双方关闭连接:服务端是关闭客户端socket连接
            client.close();
       }
   }
}

客户端

package org.example.tcp.demo1;
import java.io.*;
import java.net.Socket;
public class TcpClient {
    //服务端IP或域名
    private static final String SERVER_HOST = "localhost";
    //服务端Socket进程的端口号
    private static final int SERVER_PORT = 8888;
    public static void main(String[] args) throws IOException {
        // 3.创建一个客户端流套接字Socket,并与对应IP的主机上,对应端口的进程建立连接
        Socket client = new Socket(SERVER_HOST, SERVER_PORT);
        // 4.发送TCP数据,是通过socket中的输出流进行发送
        OutputStream os = client.getOutputStream();
        // 为了方便输出字符串作为发送的内容,可以将以上字节流包装为字符流
        PrintWriter pw = new PrintWriter(new OutputStreamWriter(os, "UTF-8"));
        // 4-1.发送数据:
        pw.println("hello world!");
        // 4-2.有缓冲区的IO操作,真正传输数据,需要刷新缓冲区
        pw.flush();
        // 7.双方关闭连接:客户端关闭socket连接
        client.close();
   }
}

以上便是短连接,客户端不会收到回应。

3.2.2长连接实现代码

        客户端发送请求,服务器接收请求,然后将其分析对其作出回应,传回客户端。

服务端:

import java.io.*;
import java.net.*;


public class TCPServer {
    public static void main(String[] args) throws IOException {
        System.out.println("服务器已启动");

        // 创建ServerSocket对象,监听指定端口
        ServerSocket serverSocket = new ServerSocket(8888);

        while (true) {
            // 等待客户端连接
            Socket socket = serverSocket.accept();
            System.out.println("已连接客户端:" + socket.getInetAddress() + ":" + socket.getPort());

            // 接收客户端消息
            BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            String readLine = null;
            while ((readLine = br.readLine()) != null) {
                System.out.println("客户端消息:" + readLine);

                // 回复客户端消息
                PrintWriter pw = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()), true);
                pw.println("Server reply: " + readLine);
            }
        }
    }
}

客户端:

import java.io.*;
import java.net.*;


public class TCPClient {
    public static void main(String[] args) throws IOException {
        // 创建Socket对象,连接指定IP和端口
        Socket socket = new Socket("localhost", 8888);

        // 发送消息给服务器
        PrintWriter pw = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()), true);
        pw.println("Hello server, I am a client.");

        // 接收服务器消息
        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String readLine = null;
        while ((readLine = br.readLine()) != null) {
            System.out.println("服务器消息:" + readLine);
        }

        // 关闭资源
        br.close();
        pw.close();
        socket.close();
    }
}

四.总结

        其实,TCP的编程比UDP要难一点点,但是只要我们理解了UDP的编程实现,我们可以更方便理解TCP的编程知识。

        TCP的通信代码实现,需要操作流操作,我们需要理解充分!

   在学习本文之前,如果你有时间,我希望你可以查看一下:网络的发展史、通信基础和原理

                                                                                                TCP和UDP的由浅到深的详细讲解

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

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

相关文章

【特纳斯电子】基于物联网的指纹密码锁系统设计-实物设计

资料下载链接:基于物联网的指纹密码锁系统设计-实物设计 - 电子校园网 编号: T3732205M-SW 设计简介: 本设计是基于单片机的指纹密码锁,主要实现以下功能: 1、可通过密码解锁 2、可通过云平台解锁 3、可通过指纹解…

基于SSM+Vue的大学学术交流论坛

末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:Vue 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目:是 目录…

保姆式教程:MAC安装Android studio(包括安装JDK,Android SDK),解决gradle下载慢的问题

文章目录 参考文章安装JDK并配置环境变量安装JDK配置JDK相关的环境变量 Android studio 安装下载Android studiogradle下载慢解决方法 安装Android SDK选择jdk版本安装SDK并配置环境变量 参考文章 原文链接 原文链接 安装JDK并配置环境变量 安装JDK 下载地址 下载后双击安装…

Mongo

MongoDB MongoDB 基础 MongoDB 是什么? MongoDB 是一个基于 分布式文件存储 的开源 NoSQL 数据库系统,由 C 编写的。MongoDB 提供了 面向文档 的存储方式,操作起来比较简单和容易,支持“无模式”的数据建模,可以存储…

java处理时间-去除节假日以及双休日

文章目录 一、建表:activity_holiday_info二、java代码1、ActivitityHolidayController.java2、ActivityHolidayInfoService.java3、ActivityHolidayInfoServiceImpl.java 三、测试效果 有些场景需要计算数据非工作日的情况,eg:统计每个人每月工作日签到…

拒绝求职诈骗,工作找好学会这一招!

马上又到了一年一季的秋招时期,社会险恶,投简历石沉大海;黑心企业拖欠农民工资、非法辞退或者遭受其他不公平待遇等等诸多问题。我们如何快速识别一家企业或公司值不值得入职,在众多竞争者中,脱颖而出,拿到…

如何选择一个向量数据库:Elastic Cloud 和 Zilliz Cloud 面面观

随着以 Milvus 为代表的向量数据库在 AI 产业界越来越受欢迎,诸如 Elasticsearch 之类的传统数据库和检索系统也开始行动起来,纷纷在快速集成专门的向量检索插件方面展开角逐。 例如,在提供类似插件的传统数据库中,Elasticsearch …

SIP对讲应用

SIP对讲应用 SIP对讲是基于标准SIP协议进行通信的对讲设备 SIP对讲一般应用到固定点位,进行求助报警所使用的一个设备,一般会应用在银行、机场、公园,医护对讲,地铁等公共场所,一般还分为防水型对讲终端(…

SpringMVC源码分析(一)启动流程分析

a、SpringMVC 在启动过程中主要做了什么事情&#xff1f; SpringMVC在启动过程中是什么时候解析web.xml文件的&#xff0c;又是什么时候初始化9大内置对象的&#xff1f; <?xml version"1.0" encoding"UTF-8"?> <web-app xmlns"http://xml…

Django实现音乐网站 ⒆

使用Python Django框架做一个音乐网站&#xff0c; 本篇主要为排行榜功能及音乐播放器部分功能实现。 目录 排行榜列表 设置路由 视图处理 模板渲染 设置跳转入口 播放器功能开发 设置路由 模板页面 脚本渲染 列表渲染和播放器实现 音乐播放器列表展示关闭 总结 排…

U3d力扣基础刷题-2

移除元素 public int RemoveElement(int[] nums, int val){// int j 0;// for (int i 0; i < nums.Length; i) // {// if (nums[i] ! val)// {// nums[j] nums[i];// }// }// return j;int j0;for(int i0;i<nums.Length;i){if(nums[i]!v…

关于导出的Excel文件的本质

上篇文章中提到关于xlsx改造冻结窗格的代码&#xff0c;我是怎么知道要加pane的呢&#xff0c;加下来就把我的心路历程记录一下。 我改造之前也是没有头绪的&#xff0c;我网上查了很多&#xff0c;只告诉我如何使用&#xff0c;但源码里没有针对!freeze的处理&#xff0c;所以…

有效回收组分含量

声明 本文是学习GB-T 42944-2023 纸、纸板和纸制品 有效回收组分的测定. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1 范围 本文件描述了纸、纸板和纸制品中有效回收组分的测定方法。 本文件适用于各种纸、纸板和纸制品&#xff0c;也适用于铝箔…

单目标优化算法:墨西哥蝾螈优化算法(Mexican Axolotl Optimization,MAO)求解23个函数MATLAB

一、墨西哥蝾螈优化算法 墨西哥蝾螈优化算法&#xff08;Mexican Axolotl Optimization&#xff0c;MAO&#xff09;由Yenny Villuendas-Rey 1等人于2021年提出&#xff0c;该算法具有较强的平衡全局搜索与局部搜索能力。 参考文献&#xff1a; [1]Villuendas-Rey, Yenny, Jo…

Apollo源码

目录结构介绍 cyber 消息中间件&#xff0c;替换ros作为消息层 data 地图等生成好的数据放在这里&#xff08;其他数据待补充&#xff09; docker 容器相关 docs 文档相关 modules 定位&#xff0c;预测&#xff0c;感知&#xff0c;规划等自动驾驶模块 scripts 脚本 third_p…

工学云打卡签到自动实现关于异地时定位的问题解决|蘑菇钉

工学云打卡助手&#xff0c;能解决你在异地时每天不间断签到的问题&#xff0c;仔细看图哦 1.自动签到 2.自定义打卡地区 3.生成日周月报与总结自动发表 4.支持随机通用内容 5.支持打卡结果推送 你是否曾经因为缺乏自律而无法坚持学习目标&#xff1f;是否曾经因为无法衡量…

WorkPlus一站式解决方案,助力企业构建统一门户系统

在信息爆炸的时代&#xff0c;企业管理面临着海量的数据和各类业务应用的复杂性。如何实现信息的井然有序、高效管理&#xff0c;成为企业发展的关键。WorkPlus作为领先的品牌&#xff0c;致力于打造统一门户系统&#xff0c;为企业提供全方位的服务和解决方案。本文将以知乎的…

Java实现B树

1.介绍 B树是一种自平衡的搜索树数据结构&#xff0c;常用于数据库和文件系统中的索引结构。它具有以下好处和功能&#xff1a; 高效的查找操作&#xff1a;B树的特点是每个节点可以存储多个关键字&#xff0c;并且保持有序。通过在节点上进行二分查找&#xff0c;可以快速定位…

使用PyTorch处理多维特征输入的完美指南

&#x1f497;&#x1f497;&#x1f497;欢迎来到我的博客&#xff0c;你将找到有关如何使用技术解决问题的文章&#xff0c;也会找到某个技术的学习路线。无论你是何种职业&#xff0c;我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章&#xff0c;也欢…

WorkPlus私有部署即时通信助力企业信息安全与高效协作

在当今快速发展的商业环境中&#xff0c;高效的内部沟通对企业的成功至关重要。然而&#xff0c;在保障信息安全的同时&#xff0c;如何实现高效的协作和沟通一直是企业所面临的挑战。传统的公共即时通信平台&#xff0c;尽管提供了便利的沟通工具&#xff0c;但其数据存储和控…