【JavaEE】网络编程 TCP/UDP

news2024/9/29 13:15:44

作者主页:paper jie_博客

本文作者:大家好,我是paper jie,感谢你阅读本文,欢迎一建三连哦。

本文于《JavaEE》专栏,本专栏是针对于大学生,编程小白精心打造的。笔者用重金(时间和精力)打造,将基础知识一网打尽,希望可以帮到读者们哦。

其他专栏:《MySQL》《C语言》《javaSE》《数据结构》等

内容分享:本期将会分享网络编程相关的知识

目录

什么是网络编程

网络编程的基本概念

Socket

概念

分类

Java数据报套接字通信模型

Java流套接字通信模型

​编辑

Socket注意事项

UDP数据报套接字编程

API

DatagramSocket

构造方法

常用方法

DatagramPacket

构造方法

常用方法

InetSocketAddress

UDP代码示例 

客户端

服务端

汉译英服务器

TCP流套接字编程

API

ServerSocket

构造方法

常用方法

Socket

构造方法

常用方法

TCP代码示例

服务端

客户端


什么是网络编程

网络编程就是指网络上的主机,通过不同的进程,通过编程的方式来实现网络通信. 这里即便是一个主机,只要是不同的进程,基于网络来传输锁数据也叫网络编程.在开发过程中,一般都是一个主机运行多个进程来完成网络编程.网络编程的目的就是为网络上不同的主机来基于网络进行传输数据资源.

网络编程的基本概念

在进行网络数据传输的时候:

发送端: 就是数据发送方进程.发送端主机即为网络通信的源主机.

接收端: 及时数据接受方进程. 接收端主机即为网络通信的目标主机.

请求: 就是发送端发出的数据

响应: 就是接收端处理发送端的数据后再返回的数据

客户端: 就是获取服务的一方进程

服务器: 提供服务的进程,就称为服务端.

Socket

概念

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

分类

Socket主要对传输层分为两类:

流套接字 - TCP协议: 它的特点就是有连接,可靠传输,面向字节流,有接收,发送缓冲区,不限制大小.

数据报套接字 - UDP协议: 它的特点就是无连接, 不可靠传输, 面向数据报, 有接收缓冲区,无发送缓冲区,大小有限制一次最多为64K.

Java数据报套接字通信模型

Java中使用UDP协议通信,主要基于DatagramSocket类来创建数据报接字,且使用DatagramPacket类来作为发送或者接收数据报.发送接收UDP数据报的流程如下:

Java流套接字通信模型

Socket注意事项

1. 注意目的IP和端口号,标识了一次数据传输时发送数据的终端主机和进程.

2. 如果端口被占用,启动进程就会报错,我们需要检查这个端口被哪个进程占用.我们可以通过端口号来查看进程的方式,可以在cmd中使用命令 netstat -ano | findstr 端口号的形式可以显示对应的进程Pid.然后我们可以任务管理器中通过Pid来查找进程,可以关闭不需要使用的进程.

3. Socket编程2我们使用的是流和数据报套接字,它是基于传输层的TCP或UDP协议,但这里我们应用层也要考虑.

UDP数据报套接字编程

API

DatagramSocket

DatagramSocket是UDP的Socket,用来发送和接受数据报的.

构造方法

方法说明
DatagramSocket()创建一个UDP数据报套接字的Socket,绑定本机任意一个没有被使用的端口(一般用于客户端)
DatagramSocket(int port)创建一个UDP数据报套接字的Socket,绑定指定的端口(port),(一般用于服务端)

常用方法

⽅法说明
void receive(DatagramPacket p)从此套接字接收数据报(如果没有接收到数据报,该
⽅法会阻塞等待)
void send(DatagramPacket p)从此套接字发送数据报包(不会阻塞等待,直接发
送)
void close()关闭此数据报套接字

DatagramPacket

DatagramPacket是UDP Socket用来发送和接收的数据报

构造方法

⽅法说明
DatagramPacket(byte[] buf,int length)构造⼀个DatagramPacket以⽤来接收数据报,接收的
数据保存在字节数组(第⼀个参数buf)中,接收指定
⻓度(第⼆个参数length
DatagramPacket(byte[] buf,int offset,int length,
SocketAddress address)
构造⼀个DatagramPacket以⽤来发送数据报,发送的
数据为字节数组(第⼀个参数buf)中,从0到指定⻓
度(第⼆个参数length)。address指定⽬的主机的IP
和端⼝号

常用方法

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

构造UDP发送的数据报的时候,需要传入SocketAddress,该对象可以使用InetSocketAddress来创建,它是SocketAddress的子类.

InetSocketAddress

⽅法签名⽅法说明
InetSocketAddress(InetAddress addr,int port)创建⼀个Socket地址,包含IP地址和端⼝号

UDP代码示例 

客户端

package UDP;

import javax.xml.crypto.Data;
import java.io.IOException;
import java.net.*;
import java.util.Scanner;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: sun杰
 * Date: 2024-01-23
 * Time: 18:52
 */
public class UdpEchoClient {
    private String serverIp;
    private int serverport;
    private DatagramSocket clientsocket = null;
    public UdpEchoClient(String serverIp, int serverport) throws SocketException {
        this.serverport = serverport;
        this.serverIp = serverIp;
        clientsocket = new DatagramSocket();
    }
    public void start() throws IOException {
        System.out.println("客户端启动!!!");
        Scanner scanner = new Scanner(System.in);
        while(true) {
            System.out.print("-> ");
            if(!scanner.hasNext()) {
                break;
            }
            String request = scanner.next();
            DatagramPacket requestPacket = new DatagramPacket(request.getBytes(),
                    request.getBytes().length, InetAddress.getByName(serverIp), serverport);
            clientsocket.send(requestPacket);
            DatagramPacket responsePacket = new DatagramPacket(new byte[4096], 4096);
            clientsocket.receive(responsePacket);
            String response = new String(responsePacket.getData(), 0, responsePacket.getLength());
            System.out.println(response);
        }
    }

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

服务端

package UDP;

import javax.xml.crypto.Data;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: sun杰
 * Date: 2024-01-23
 * Time: 18:53
 */
public class UdpEchoServer {
    private DatagramSocket serverSocket = null;
    public UdpEchoServer(int port) throws SocketException {
        serverSocket = new DatagramSocket(port);
    }
    public void start() throws IOException {
        System.out.println("服务器启动!!!");
        while(true) {
            //1.接收并解析请求
            DatagramPacket datagramPacket = new DatagramPacket(new byte[4096], 4096);
            serverSocket.receive(datagramPacket);
            String request = new String(datagramPacket.getData(), 0, datagramPacket.getLength());//有效长度
            String response = process(request);
            //2.返回响应
            DatagramPacket responsePacket = new DatagramPacket(response.getBytes(),  response.getBytes().length,
                    datagramPacket.getSocketAddress());
            serverSocket.send(responsePacket);
            //3.打印日志
            System.out.printf("[%s : %d] req: %s resp: %s\n", datagramPacket.getAddress(),
                    datagramPacket.getPort(), request, response);
        }
    }

    public String process(String request) {
        return request;
    }

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

汉译英服务器

package UDP;

import java.io.IOException;
import java.net.SocketException;
import java.util.HashMap;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: sun杰
 * Date: 2024-01-23
 * Time: 19:38
 */
public class UdpDictServer extends UdpEchoServer{
    private HashMap<String, String> dict = new HashMap<>();

    public UdpDictServer(int port) throws SocketException {
        super(port);
        dict.put("cat", "喵喵");
        dict.put("dog", "狗叫");
        dict.put("fuck", "你妈的");
    }
    @Override
    public String process(String request) {
        return dict.getOrDefault(request, "该词不存在");
    }

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

TCP流套接字编程

API

ServerSocket

ServerSocket是创建TCP服务端Socket的API.

构造方法

⽅法说明
ServerSocket(int port)创建⼀个服务端流套接字Socket,并绑定到指定端⼝

常用方法

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

Socket

Socket是客户端Socket,或服务端中接收到客户端的连接的请求后,返回的服务端Socket.这里的Socket是保存对端的信息,以及用来和对对方收发数据的.

构造方法

⽅法说明
Socket(String host, int port)创建⼀个客⼾端流套接字Socket,并与目标IP的主机
上,目标端⼝的进程建⽴连接

常用方法

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

TCP代码示例

服务端

package TCP;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: sun杰
 * Date: 2024-01-24
 * Time: 14:25
 */
public class TcpEchoServer {
    private ServerSocket serverSocket = null;
    public TcpEchoServer(int port) throws IOException {
        serverSocket = new ServerSocket(port);
    }
    public void start() throws IOException {
        System.out.println("服务器启动");
        ExecutorService service = Executors.newCachedThreadPool();
        while(true) {
            Socket clientSocket = serverSocket.accept();
            //使用线程池
            service.submit(() -> {
                try {
                    processConnection(clientSocket);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            });
            //创建多线程
            /*Thread t = new Thread(() -> {
                try {
                    processConnection(clientSocket);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            });
            t.start();
        }*/
        }
    }
    public void processConnection(Socket clientSocket) throws IOException {
        try(InputStream inputStream = clientSocket.getInputStream();
            OutputStream outputStream = clientSocket.getOutputStream()) {
            System.out.printf("[%s : %d] 客户端上线!!!\n", clientSocket.getInetAddress(), clientSocket.getPort());
            Scanner scanner = new Scanner(inputStream);
            PrintWriter writer = new PrintWriter(outputStream);
            while(true) {
                //1. 读取请求并解析
                if(!scanner.hasNext()) {
                    System.out.printf("[%s : %d] 客户端下线!!!", clientSocket.getInetAddress(), clientSocket.getPort());
                    break;
                }
                String request = scanner.next();
                String response = process(request);
                //2. 返回响应
                writer.println(response);
                writer.flush();
                //3. 打印日志
                System.out.printf("[%s : %d] req: %s resp: %s\n", clientSocket.getInetAddress(),
                        clientSocket.getPort(), request, response);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }finally {
            clientSocket.close();
        }
    }
    public String process(String request) {
        return request;
    }

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

客户端

public class TcpEchoClient {
    private Socket socket = null;
    public TcpEchoClient(String serverIp, int serverPort) throws IOException {
        socket = new Socket(serverIp, serverPort);
    }
    public void start() {
        System.out.println("客户端启动");
        try(InputStream inputStream = socket.getInputStream();
            OutputStream outputStream = socket.getOutputStream()) {
            Scanner scannerConsole = new Scanner(System.in);
            Scanner scannerNetwork = new Scanner(inputStream);
            PrintWriter writer = new PrintWriter(outputStream);
            while(true) {
                System.out.print("-> ");
                if(!scannerConsole.hasNext()) {
                    break;
                }
                String request = scannerConsole.next();
                //1. 发送请求
                writer.println(request);
                writer.flush();
                //2. 接受响应
                String response = scannerNetwork.next();
                //3. 打印响应
                System.out.println(response);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

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

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

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

相关文章

WorkPlus移动应用管理平台,助力企业实现高效移动办公

在移动办公成为当今工作方式的主流趋势下&#xff0c;管理和运营企业移动应用成为了提高工作效率和数据安全的重要环节。而移动应用管理平台作为实现移动办公高效管理的关键工具&#xff0c;WorkPlus以其领先的性能和全面的功能&#xff0c;助力企业实现高效移动办公。 为何选…

【医学图像数据增强】切割-拼接(CS-DA)

切割-拼接CS-DA CS-DA 核心思想自然图像和医学图像之间的关键差异CS-DA 步骤确定增强后的数据数量 代码复现 CS-DA 核心思想 论文链接&#xff1a;https://arxiv.org/ftp/arxiv/papers/2210/2210.09099.pdf 大多数用于医学分割的数据增强技术最初是在自然图像上开发的&#x…

【Docker】Kubernetes 命令行 kubectl(kubectl 使用)

作者主页&#xff1a; 正函数的个人主页 文章收录专栏&#xff1a; Docker 欢迎大家点赞 &#x1f44d; 收藏 ⭐ 加关注哦&#xff01; kubectl 使用 kubectl 是 Kubernetes 自带的客户端&#xff0c;可以用它来直接操作 Kubernetes。 使用格式有两种&#xff1a; kubectl […

C#hybridCLR热更新方案初探

前言 暂时处于初步研究状态&#xff0c;目前的框架使用还是尚少&#xff0c;本篇文章旨在同步给大家大概的使用流程和使用心得&#xff0c;在初步建立新项目时可以适当考虑。 介绍 热更新 与强制更新相对应&#xff0c;移动平台上App的可执行程序没有发生变化&#xff0c;仅…

免费畅享,打破写作瓶颈:星火写作助手覆盖全面,助你轻松创作

啰嗦几句 最近年终岁末&#xff0c;公司的各种文案各种总结&#xff0c;写得人是头晕脑胀&#xff0c;所以好多小伙伴最近在求智能写作的软件&#xff0c;最好是ChatGPT。 ChatGPT是国外产品&#xff0c;在国内并不能访问。而就智能写作来说&#xff0c;我们何必舍近求远呢&am…

flutter极光推送配置厂商通道(华为)笔记--进行中

一、基础集成按照下面官方文档进行 厂商通道相关参数申请教程 集成厂商 集成指南 官方文档&#xff1a;厂商通道回执配置指南 注意&#xff1a;不同厂商对app上架的要求不同&#xff0c;华为、荣耀 对app上架没有硬性要求 遇到问题 1、引入apply plugin: com.huawei.agconn…

2023-2024年重庆职业院校技能大赛“信息安全管理与评估”比赛样题

2023 年重庆职业院校技能大赛&#xff08;高等职业教育&#xff09; “信息安全管理与评估”样题任务书 第一阶段&#xff1a;任务 1 网络平台搭建&#xff08;50 分&#xff09;任务 2 网络安全设备配置与防护&#xff08;250 分&#xff09; 第二阶段&#xff1a;第一部分 网…

GoZero微服务个人探究之路(九)api文件编写总结

参考来源go-zero官方文档https://go-zero.dev/docs/tutorials 前言 go-zero是目前star最多的go语言微服务框架&#xff0c;api 是 go-zero特殊的语言&#xff0c;类型文件&#xff0c;go-zero自带的goctl可以通过.api文件生成http服务代码 api文件内容编写 不可使用关键字 …

Chrome 插件调试

http://blog.haoji.me/chrome-plugin-develop.html#te-bie-zhu-yi-background-de-bao-cuo 手把手&#xff1a;Chrome浏览器开发系列(四)&#xff1a;调试我们开发的插件 - 掘金

iOS推送通知

文章目录 一、推送通知的介绍1. 简介2. 通知的分类 二、本地通知1. 本地通知的介绍2. 实现本地通知3. 监听本地通知的点击 三、远程通知1. 什么是远程通知2. 为什么需要远程通知3. 远程通知的原理4. 如何做远程通知5. 远程通知证书配置6. 获取远程推送要用的 DeviceToken7. 测试…

技术解读 | KunDB助力头部金融机构关键系统的Oracle国产替代

星环科技自主研发的分布式交易型数据库KunDB助力头部金融机构实现了关键系统的Oracle国产化替代。 通过可视化迁移工具完成了对象与数据的平滑迁移&#xff0c;将原先两套Oracle系统&#xff08;一套Oracle单机系统&#xff0c;一套Oracle RAC系统&#xff09;统一迁移到一套K…

运动戴什么耳机好?怎样选运动耳机?2024年运动蓝牙耳机推荐

​运动耳机作为运动人士的得力助手&#xff0c;不仅要求佩戴舒适&#xff0c;还需要在音质表现、防水性能、通话质量等方面有出色表现。下面我为大家推荐几款性能全面的运动耳机&#xff0c;希望能满足不同需求的运动爱好者&#xff0c;来看看吧。 1.南卡开放式耳机&#xff08…

02-TiDB部署本地测试集群

基于v7.5版本 1、下载并安装 TiUP curl --proto https --tlsv1.2 -sSf https://tiup-mirrors.pingcap.com/install.sh | sh 下载后路径/root/.tiup&#xff0c;已自动将环境变量写入文件中&#xff0c;需要手动执行source source /root/.bashrc 2、在当前 session 执行以下命令…

深入理解3D扩散生成式模型

Stable Dreamfusion 上的这个存储库启发了这个博客。 我认为 3D 扩散和 3D 生成似乎是每个人心中的下一件大事。 Stability AI 开始招聘才华横溢的 3D AI 工程师&#xff0c;谷歌和学术界每天似乎都在进行令人印象深刻的即时 3D 模型生成器研究。 然而&#xff0c;虽然我对这些…

GuitarPro和Earmaster那个适合新手

许久没发文了&#xff0c;最近在网上刷到了一位音乐UP主从容Free&#xff0c;他把自己对GuitarPro和Earmaster这2款软件的使用感受进行了详细分享&#xff0c;还没看过的朋友可以戳下面的链接跳转到小破站看完整的&#xff1a; 我不允许还有人不知道这个学吉他的神器&#xff…

专业140+总分420+复旦大学957信号与系统考研经验复旦电子信息与通信

今年专业957信号与系统140&#xff0c;数二140&#xff0c;总分420&#xff0c;顺利上岸复旦大学&#xff0c;回顾这一年的复习&#xff0c;有起有落&#xff0c;也有过犹豫和放弃&#xff0c;好在都坚持下来了&#xff0c;希望大家考研复习要不忘初心&#xff0c;困难肯定是很…

深度学习(5)--Keras实战

目录 一.Keras基础概念 二.如何跑通Keras项目 2.1.在cmd上跑通 2.2.在PyCharm上跑通 一.Keras基础概念 Keras是深度学习中的一个神经网络框架&#xff0c;是一个高级神经网络API&#xff0c;用Python编写&#xff0c;可以在TensorFlow&#xff0c;CNTK或Theano之上运行。 …

【labVIEW】学习记录

【labVIEW】学习记录 一、简介二、安装及激活三、使用 回到目录 一、简介 labVIEW&#xff08;Laboratory Virtual Instrument Engineering Workbench&#xff09;是一款由美国国家仪器公司&#xff08;National Instruments&#xff09;开发的可视化编程环境和开发平台。LabV…

Windows在局域网内开启共享文件夹

局域网内多台电脑开启共享文件夹可以提高使用舒适度&#xff0c;而共享文件夹的设置方式也非常简单。 1、开启网络共享 1.1 确定网络类型&#xff1a;公用or专用 首先我们需要确定自己的网络类型&#xff0c;首先从网络和共享中心可以看到我的电脑连接了一个wifi&#xff0c…