首页 > 编程语言 >JAVAEE之网络编程(1)_套接字、UDP数据报套接字编程及从代码实例

JAVAEE之网络编程(1)_套接字、UDP数据报套接字编程及从代码实例

时间:2024-06-09 12:04:39浏览次数:17  
标签:UDP DatagramPacket String 编程 new 接字 数据 客户端

前言

什么是网络编程呢?
 网络编程,指网络上的主机,通过不同的进程,以编程的方式实现网络通信(或称为网络数据传输)。当然,即便是同一个主机,只要是不同进程,基于网络来传输数据,也属于网络编程

一、网路编程中的基本概念

1.1 发送端和接收端

  1. 发送端:数据的发送方进程,称为发送端。发送端主机即网络通信中的源主机。
  2. 接收端:数据的接收方进程,称为接收端。接收端主机即网络通信中的目的主机。
  3. 收发端:发送端和接收端两端,也简称为收发端。

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

请求和响应

一般来说,获取一个网络资源,涉及到两次网络数据传输:

  1. 第一次:请求数据的发送
  2. 第二次:响应数据的发送。

客户端和服务端

客户端和服务端:

  1. 服务端:在常见的网络数据传输场景下,把提供服务的一方进程,称为服务端,可以提供对外服务。
  2. 客户端:获取服务的一方进程,称为客户端。

二、Socket 套接字

2.1 基本概念

Socket套接字,是由系统提供用于网络通信的技术,是基于TCP/IP协议的网络通信的基本操作单元。基于Socket套接字的网络程序开发就是网络编程。

2.2数据报套接字:使用传输层UDP协议

UDP,即User Datagram Protocol(用户数据报协议),传输层协议。
UDP的主要特点:(详细内容会在后续的章节中详细介绍)

  1. 无连接
  2. 不可靠传输
  3. 面向数据报
  4. 有接收缓冲区,无发送缓冲区
  5. 大小受限:一次最多传输 64KB

 对于数据报来说,可以简单的理解为,传输数据是一块一块的,发送一块数据假如100个字节,必须一次发送,接收也必须一次接收100个字节,而不能分100次,每次接收1个字节。

三、UDP数据报套接字编程

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

 对于UDP协议来说,具有无连接,面向数据报的特征,即每次都是没有建立连接,并且一次发送全部数据报,一次接收全部的数据报。
 java中使用UDP协议通信,主要基于 DatagramSocket 类来创建数据报套接字,并使用DatagramPacket 作为发送或接收的UDP数据报

对于一次发送及接收UDP数据报的流程如下:
在这里插入图片描述

3.2 DatagramSocket API

DatagramSocket 是UDP Socket,用于发送和接收UDP数据报。
DatagramSocket 构造方法:
在这里插入图片描述
DatagramSocket 方法:
在这里插入图片描述

3.3 DatagramPacket API

DatagramPacket是UDP Socket发送和接收的数据报。
DatagramPacket 构造方法:
在这里插入图片描述
 构造UDP发送的数据报时,需要传入 SocketAddress ,该对象可以使用 InetSocketAddress 来创建。
InetSocketAddress ( SocketAddress 的子类 )构造方法:
在这里插入图片描述

DatagramPacket 方法:
在这里插入图片描述

以下为服务端和客户端代码:

UDP服务端:

package network;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.nio.channels.DatagramChannel;

/**
 * @author Zhang
 * @date 2024/5/2015:38
 * @Description:
 */
public class UdpEchoServer {

    //创建一个datagramSocket对象,这是后续操作网卡的基础
    private DatagramSocket socket = null;

    public UdpEchoServer(int port) throws SocketException {
        //此写法是手动指定端口
        socket = new DatagramSocket(port);

        // 此写法是让服务器自动分配端口
       // socket = new DatagramSocket();

    }

    //通过这个方法来启动服务器
    public void start() throws IOException {
        System.out.println("服务器启动");

        while(true){
            // 1. 读取请求并解析
            /**
             *  DatagramPacket这个队形来承载从网卡这边读取的数据,
             *  收到的数据需要一个内存空间来保存这个数据
             *  DatagramPacket 内部不能自动分配空间,需要程序员手动创建,交给DatagramPacket进行处理
             */
            DatagramPacket requestPacket  = new DatagramPacket(new byte[4096],4096);
            socket.receive(requestPacket);   //当服务器一旦启动,就会立即执行receive方法,入伏哦客户端请求还没到,receive就会阻塞到客户端请求到达
            // 当完成receive后,数据以二进制的形式存储到DatagramPacket
            // 要想把这里的数据显示出来,好需要把这个二进制转变成字符串
            String request = new String(requestPacket.getData(),0,requestPacket.getLength());

            // 2.根据请求计算响应(一般服务器都会经理的过程)
            // 由于此处是回显服务器,请求是啥样,响应就是啥样
            String response = process(request);

            // 3. 把响应写会到客户端
            //      写一个响应对象,DatagramPacket
            //      往DatagramPacket 构造刚才数据,并通过 sent 返回

            DatagramPacket responsePacket = new DatagramPacket(response.getBytes(),response.getBytes().length,requestPacket.getSocketAddress());
            // 构造这个数据报,需要指定数据内容,也指定下一个数据报要发给谁
            socket.send(responsePacket);

            // 4.打印一个日志,把这次数据交互的详情打印出来
            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();
    }
}

UDP客户端

package network;

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

/**
 * @author ZhangXu
 * @date 2024/5/2015:38
 * @Description:
 */
public class UdpEchoClient {

    private DatagramSocket socket = null;
    private  String serverIP = "";
    private  int serverPort = 0;

    public  UdpEchoClient(String ip,int port) throws SocketException {
        // 创建这个对象,不能手动指定端口
      socket = new DatagramSocket();
      //由于UDP自身不会持有对端的信息,就需要在应用程序里,吧对端的情况给记录下来
        serverIP = ip;
        serverPort = port;
    }


    public void start() throws IOException {
        System.out.println("客户端启动!");
        Scanner scanner = new Scanner(System.in);
        while (true){
            // 1.从控制台读取数据,作为请求
            System.out.print("->");
            String request = scanner.next();
            // 2. 把请求内容构造成 DatagramPacket 对象,发送给服务器
            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);
            // 4.把响应转换成字符串,并先显示出来
            String response =  new String(responsePacket.getData(),0,responsePacket.getLength());
            System.out.println(response);
        }
    }


    public static void main(String[] args) throws IOException {
        UdpEchoClient client = new UdpEchoClient("127.0.0.1", 9090);
        client.start();
    }

}


 启动客户端和服务端,在客户端发送内容,在服务端将会接收到相同的信息,运行结果:

UdpEchoClient:   
	客户端启动!
	->xiaoming
	xiaoming
->

UdpEchoClient:   
	服务器启动
	[/127.0.0.1:51575] req = xiaoming, resp = xiaoming

我们在下一节内容将会介绍TCP流套接字编程相关内容。

标签:UDP,DatagramPacket,String,编程,new,接字,数据,客户端
From: https://blog.csdn.net/2301_80653026/article/details/139443856

相关文章

  • 实验6 C语言结构体、枚举应用编程
    //task4.c#include<stdio.h>#include<stdlib.h>#include<string.h>#defineN10typedefstruct{charisbn[20];//isbn号charname[80];//书名charauthor[80];//作者doublesales_price;//售价int......
  • 实验6 C语言结构体、枚举应用编程
    task.1#defineN3//运行程序输入测试时,可以把这个数组改小一些输入测试#include<stdlib.h>typedefstructstudent{intid;//学号charname[20];//姓名charsubject[20];//考试科目doubleperf;//......
  • 程序员学习Processing和TouchDesigner视觉编程相关工具
     ProessingProcessing是一种用于视觉艺术和创意编程的开发环境和编程语言。它最初是为了帮助非专业程序员学习编程,特别是那些对于创意编程和视觉表达感兴趣的人。Processing提供了简单易用的API,使得绘制图形、创建动画和交互式应用变得相对容易。在前端应用Processing......
  • 实验6 C语言结构体、枚举应用编程
    task1.c1//P286例8.172//对教材上的程序作了微调整,把输出学生信息单独编写成一个函数模块3//打印不及格学生信息和所有学生信息程分别调用45#include<stdio.h>6#include<string.h>7#defineN3//运行程序输入测试时,可以把这个数组......
  • 【机器学习基础】Python编程07:五个实用练习题的解析与总结
    Python是一种广泛使用的高级编程语言,它在机器学习领域中的重要性主要体现在以下几个方面:简洁易学:Python语法简洁清晰,易于学习,使得初学者能够快速上手机器学习项目。丰富的库支持:Python拥有大量的机器学习库,如scikit-learn、TensorFlow、Keras和PyTorch等,这些库提供了......
  • 【机器学习基础】Python编程08:五个实用练习题的解析与总结
    Python是一种广泛使用的高级编程语言,它在机器学习领域中的重要性主要体现在以下几个方面:简洁易学:Python语法简洁清晰,易于学习,使得初学者能够快速上手机器学习项目。丰富的库支持:Python拥有大量的机器学习库,如scikit-learn、TensorFlow、Keras和PyTorch等,这些库提供了......
  • Python_编程基础
    Python_编程基础Python编程基础0、简单介绍解释型语言:一边编译一边运行,不需要进行编译,运行效率比较低解释器JavaScript-浏览器python.exephp.exe编译型语言:运行前需要进行编译,运行效率比较高C.c->.exe组合:anaconda+pycharm、python+pycharm/sublime/geany/vs......
  • Postgres 查询中的宏/元编程
    如果我拥有与本问题中相同的示例数据,并另外声明了以下两个函数:创建或替换函数example.markout_666_example_666_price_table_666_price(_symboltext,_time_oftimestamptz,_startinterval,_durationinterval)返回float8LANGUAGEsqlSTABLESTRICTPARA......
  • 嵌入式Linux系统编程 — 3.1 Linux系统中的文件类型
    目录1Linux系统中的文件类型简介2普通文件2.1什么是普通文件2.2普通文件分类3 目录文件4 字符设备文件和块设备文件4.1什么是设备文件4.2查看设备文件的方法:5 符号链接文件(link)5.1什么是符号链接文件5.2如何查看和创建符号链接文件6 管道文件7 套接......
  • C++:Traits编程技法在STL迭代器中的应用
    文章目录迭代器相应型别Traits(特性)编程技法——STL源代码门钥迭代器相应型别一:value_type迭代器相应型别二:difference_type迭代器相应型别三:reference_type迭代器相应型别四:pointer_type迭代器相应型别五:iterator_category以`advanced()`为例取消单纯传递调用的函数以`......