简述

上一篇博客展示了如果A对b通过微信发了个“在吗”是多么的复杂,但事实上,我们写代码并不需要掌握其中的所有细节,操作系统给应用程序提供了一系列API,我们只需要按照对应的格式,就可以实现网络编程了

网络传输层中有许多的协议,其中最著名的是TCP和UDP,操作系统根据这两个协议,提供了两种不同的API

TCP和UDP区别

TCP的特点:有连接,可靠传输,面向字节流,全双工
UDP的特点:无连接,不可靠传输,面向数据报,全双工

有连接/无连接

有连接就是发送方和接收方必须建立好连接后才能互相通信,例如打电话,必须接受者接听了电话,两个人才能聊天,而无连接就相当于发微信,接受者不需要时时刻刻看微信才能收到消息

可靠传输/不可靠传输

由于网络环境十分复杂,稍微有一层的数据传输有问题,整体的传输就失败了,因此如果说发送方能够知道接受方收到消息了,就是可靠传输,否则就是不可靠传输

面向字节流/面向数据报

和我们之前讲的读写文件一样,传输数据也是有基本单位的,面向字节流就是以字节为基本单位进行传输,面向数据报就是以数据报为基本单位

全双工/半双工

全双工就是一个通道,双向通信
半双工就是一个通道,单向通信

我们的网络通信一半都是全双工的,一根网线可以同时上传和下载,也就是说一根网线是双向通信的

UDP socket

java提供了两个类,DatagramSocket,DatagramPacket
DatagramSocket是网卡的代言人,DatagramPacket代表一个UDP数据报

DatagramSocket

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

构造方法

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

方法

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

这里我们发现和文件的使用差不多,其实socket本质上也是文件,操作系统将各种硬件设备抽象成了文件,方便进行管理和调用,通过网卡发送数据,就相当于写文件,通过网卡接受数据就相当于读文件

DatagramPacket

是UDP发送和接收的数据报

构造方法

构造方法 说明
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版本回显服务器,客户端

回显服务器也就是客户端发送什么数据,接受方就返回什么信息,也就是复读机

UdpEchoServer

package net;import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.nio.charset.StandardCharsets;public class UdpEchoServer {private DatagramSocket socket = null;/*** 参数的端口代表服务器要绑定的端口* @param port* @throws SocketException*/public UdpEchoServer(int port) throws SocketException {socket = new DatagramSocket(port);//表示自己要连接哪个端口 服务器的Ip一般不用写——就是本机的Ip}/*** 启动服务器* @throws IOException*/public void start() throws IOException {System.out.println("服务器启动!");while(true){//接收请求DatagramPacket requestPacket = new DatagramPacket(new byte[4096],4096);//构造空的packet//为Packet申请内存空间socket.receive(requestPacket);//输出型参数,构造一个空的DatagramPacket对象,网卡将数据填充到这个对象中String request = new String(requestPacket.getData(), 0, requestPacket.getLength());//根据请求计算响应String response = process(request);//发送响应DatagramPacket responsePacket = new DatagramPacket(response.getBytes(),response.getBytes().length,requestPacket.getSocketAddress());//构造有数据的packet,使用InetAddress描述发送地址socket.send(responsePacket);//打印日志System.out.printf("[%s:%d] req: %s; resp: %s",requestPacket.getAddress().toString(),requestPacket.getPort(),request,response);System.out.println();}}/*** 根据请求构造响应* @param request* @return*/public String process(String request) {return request;}public static void main(String[] args) throws IOException {UdpEchoServer udpEchoServer = new UdpEchoServer(9090);//服务器端口号udpEchoServer.start();}
}

我们服务器的端口号可以从0到65535,但是0到1023一般都被著名的应用程序使用了,被称之为知名端口号,因此我们一般使用1024到65535

UdpEchoClient

package net;import java.io.IOException;
import java.net.*;
import java.util.Scanner;public class UdpEchoClient {private DatagramSocket socket = null;private String serverIp;private int serverPort;public UdpEchoClient(String serverIp, int serverPort) throws SocketException {socket = new DatagramSocket();//系统会自动分配端口this.serverPort = serverPort;this.serverIp = serverIp;}private void start() throws IOException {while(true){//读取用户输入内容Scanner scanner = new Scanner(System.in);System.out.print("-> ");String request = scanner.next();//构造请求,发送给服务器DatagramPacket requestPacket = new DatagramPacket(request.getBytes(),request.getBytes().length,InetAddress.getByName(this.serverIp),this.serverPort);//构造有数据的packet,通过Ip和端口号描述地址socket.send(requestPacket);//读取服务器响应数据DatagramPacket responsePacket = new DatagramPacket(new byte[4096],4096);socket.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);//目的服务器Ip——本机Ip,目的服务器端口udpEchoClient.start();}}

Udp版本翻译服务器,客户端

本质上,翻译服务器就是通过大量存储英文和对应中文的键值对来实现翻译的功能,我们通过继承并重写回显服务器的process方法,可以实现翻译服务器的核心功能。

UdpTranslateServer

import java.io.IOException;
import java.net.SocketException;
import java.util.HashMap;
import java.util.Map;public class UdpTranslateServer extends UdpEchoServer{private Map<String, String> dict = new HashMap<>();/*** 参数的端口代表服务器要绑定的端口** @param port* @throws SocketException*/public UdpTranslateServer(int port) throws SocketException {super(port);dict.put("cat","猫");dict.put("dog","狗");dict.put("handsome","李骁");}//重写process方法@Overridepublic String process(String request){return dict.getOrDefault(request,"error");}public static void main(String[] args) throws IOException {UdpEchoServer udpEchoServer = new UdpTranslateServer(8090);udpEchoServer.start();}
}

UdpTranslateClient

和我们的回显客户端代码一致

Java EE——网络编程套接字UDP相关推荐

  1. 详细讲解 —— 网络编程套接字(Java EE初阶)

    网络编程套接字 1 认识网络编程套接字 2 UDP 数据报套接字编程 2.1 UPD服务端 2.1 UDP客户端 2.3 结果测试 3 TCP流套接字编程 3.1 TCP服务端 3.2 TCP客户端 ...

  2. Java网络编程套接字

    文章目录 1.网络编程基础 2.什么是网络编程 3.网络编程中的基本概念 3.1.发送端和接收端 3.2 请求和响应 3.3 客户端和服务端 3.4 常见的客户端服务端模型 4.Socket套接字 4 ...

  3. 【javaEE】网络编程套接字

    To u&me: 努力经营当下,直至未来明朗 文章目录 前言 一.网络编程(没时间可以跳过) 一)网络编程了解 二)相关基本概念 二.Socket套接字 三.数据报套接字通信(UDP) 写一个 ...

  4. 网络编程套接字(二)

    网络编程套接字(二) 文章目录 网络编程套接字(二) 一.简单的UDP网络程序 一.简单的UDP网络程序 封装udp_socket #pragma once #include <cstdio&g ...

  5. 网络编程套接字(一)

    网络编程套接字(一) 文章目录 网络编程套接字(一) 一.基础知识 二.sock编程接口 一.基础知识 1. 理解源IP地址和目的IP地址 在IP数据包头部中,有两个IP地址,分别叫源IP地址和目的I ...

  6. UNIX网络编程---套接字编程简介(三)

    UNIX网络编程---套接字编程简介 一.概述 从这里开始正式开始网络编程之旅,所有的函数都是基本的库函数.这些都是网络编程的基础.Come on!!!! 二.套接字地址结构 大多数套接字函数都需要一 ...

  7. 【网络编程套接字(一)】

    网络编程套接字(一) 理解源IP地址和目的IP地址 理解源MAC地址和目的MAC地址 理解源端口号和目的端口号 PORT VS PID 认识TCP协议和UDP协议 网络字节序 socket编程接口 s ...

  8. Linux·网络编程套接字(三)

    目录 简单的TCP英译汉服务器 简单回顾 更改handler方法 地址转换函数 字符串IP转整数IP 整数IP转字符串IP 绑定失败问题 TCP协议通讯流程 通讯流程总览 三次握手的过程 数据传输的过 ...

  9. 网络编程套接字(四)

    网络编程套接字(四) 文章目录 网络编程套接字(四) 一.实现tcp服务器多用户版本(多进程.多线程.线程池版本) 一.实现tcp服务器多用户版本(多进程.多线程.线程池版本) tcp_process ...

最新文章

  1. HTML5调用手机的Datepicker(日期选择器)
  2. iOS 使用Quartz 2D画虚线 .
  3. 没有“好的”数据,AI就没有未来?听听云测数据怎么说
  4. C++11中正則表達式測试
  5. POJ3784-Running Median(运行中位数)【链表】
  6. tomcat CATALINA_HOME与CATALINA_BASE的区别
  7. 页面显示其他php,php – 分页在所有其他页面上显示来自第1页的相同帖子
  8. 加快linux编译速度,Linux Makefile 编译速度的优化【转】
  9. 图片字符串base64的判断
  10. Mvc 翻页查询,代码很有用
  11. 长虹电视+刷回android,【原创教程】长虹智能电视Q3T手动升级and刷机救砖教程
  12. 移动硬盘计算机管理无法显示,为什么移动硬盘插在电脑上不显示_移动硬盘为什么在电脑上面显示不出来-系统城...
  13. 景观生态学原理| 8 景观生态学与生物多样性保护
  14. 【Beetl笔记整理七】格式化
  15. 【正则表达式】自动生成各类正则代码
  16. 如何在上传的图片上写字
  17. 青年不愿老去,“养生+奶茶”却撑不起这份骄傲倔强
  18. dbcc dbreindex server sql_SQL Server2005索引碎片分析和解决方法
  19. 单片机国产替代选型合集,势在必行!
  20. 小胖机器人宣传语_机器人教育创意口号

热门文章

  1. Sparrow——数据库脚本
  2. html5游戏存档,别出机杼,这些游戏把存档玩出了花
  3. Telegram Chat Bot采坑日记
  4. 100道Java实习生需要掌握的面试问题
  5. mysql 顿号_mysql使用常见错误
  6. python3.7实现福彩双色球购票系统(单机版)
  7. cod16一进单机就断开服务器无响应,使命召唤16刚登录进游戏就闪退
  8. 计算机研究专业学校排名,研究生计算机专业学校排名
  9. 【目录】成为独立开发者
  10. cas:1628790-40-8|脂溶性Cyanine7-COOH|CY7-Carboxylic Acid