目录

网络开发

套接字

Java中使用UDP协议,相关的类介绍

DatagramSocket API

DatagramPacket API

InetSocketAddress API

服务器和客户端

Java数据报套接字通信模型

演示

TCP流套接字编程

ServerSocket API

Socket API

面向数据报文和面向字节流


网络开发

套接字

套接字(Socket):站在应用层,做网络编程很重要的一个概念

OS原生的提供的系统调用(Linux上的网络编程)

int fd = socket();
setsocketopt(fd,TCP or UDP)

Java中使用UDP协议,相关的类介绍

DatagramSocket API

DatagramSocket 是UDP Socket,用于发送和接收UDP数据报。

DatagramSocket 构造方法:

DatagramSocket 构造方法:

DatagramPacket API

DatagramPacket是UDP Socket发送和接收的数据报。
DatagramPacket 构造方法:

DatagramPacket 方法:

InetSocketAddress API

InetSocketAddress ( SocketAddress 的子类 )构造方法:

服务器和客户端

服务器(Server):提供服务(Service)的一类程序,一般这个概念是应用层概念。
想象成生活中的:一家商店(提供售卖货品服务)、一家饭馆(提供售卖食品服务)、一家律师事务所(提供法律咨询服务)
淘宝(提供了淘宝平台服务).….
我们这里的服务器指的是一个具体的进程。广义上,我们也经常把该进程所在的主机也称为服务器。由于服务器需要对外提供服务(开张营业),所以,服务器都需要公开其地址(ip / port)。

客户端(Client):享受服务的角色

客户端和服务器双方的常见模式,一般有两种:

1.请求(Request)-响应(Response)模式

1)客户端主动提出自己的要求(点菜)
2)服务器根据请求,给回响应(上菜)

服务器是被动的

这个周期可能在一个客户端、服务器内部发生多次。一次请求一次响应最简单,我们只展示这种模式。

2.订阅(subscript) -广播(broadcase)模式订报纸
1)客户端第一次主动订阅某份报纸(关心某些消息)
2)以后,凡是这份报纸有新的信息,服务器就会主动推给客户端
服务器相对来说是主动的

Java数据报套接字通信模型

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

对于一次发送及接收UDP数据报的流程如下:

以上只是一次发送端的UDP数据报发送,及接收端的数据报接收,并没有返回的数据。也就是只有请求,没有响应。


对于一个服务端来说,重要的是提供多个客户端的请求处理及响应,流程如下:

演示

import com.xxx.net_demo.util.Log;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketAddress;
import java.util.Arrays;
import java.util.HashMap;// 提供翻译的服务器
public class TranslateServer {// 公开的 ip 地址:就看进程工作在哪个 ip 上// 公开的 port:需要程序中指定public static final int PORT = 8888;// SocketException -> IOException -> Exceptionpublic static void main(String[] args) throws Exception {Log.println("准备进行字典的初始化");initMap();Log.println("完成字典的初始化");Log.println("准备创建 UDP socket,端口是 " + PORT);DatagramSocket socket = new DatagramSocket(PORT);Log.println("UDP socket 创建成功");// 作为服务器,是被动的,循环的进行请求-响应周期的处理// 等待请求,处理并发送响应,直到永远while (true) {// 1. 接收请求byte[] buf = new byte[1024];    // 1024 代表我们最大接收的数据大小(字节)DatagramPacket receivedPacket = new DatagramPacket(buf, buf.length);Log.println("准备好接收 DatagramPacket,最大大小为: " + buf.length);Log.println("开始接收请求");socket.receive(receivedPacket); // 这个方法就会阻塞(程序执行到这里就不动了,直到有客户发来请求,才能继续)Log.println("接收到请求");// 2. 一旦走到此处,一定是接收到请求了,拆信// 拆出对方的 ip 地址InetAddress address = receivedPacket.getAddress();Log.println("对方的 IP 地址: " + address);// 拆出对方的端口int port = receivedPacket.getPort();Log.println("对方的 port: " + port);// 拆出对方的 ip 地址 + portSocketAddress socketAddress = receivedPacket.getSocketAddress();Log.println("对象的完整地址: " + socketAddress);// 拆出对方发送过来的数据,其实这个 data 就是我们刚才定义的 buf 数组byte[] data = receivedPacket.getData();Log.println("接收到的对象的数据: " + Arrays.toString(data));// 拆出接收到的数据的大小(字节)int length = receivedPacket.getLength();Log.println("接收的数据大小(字节):" + length);// 3. 解析请求 :意味着我们需要定义自己的应用层协议// 首先,做字符集解码    byte[] -> StringString request = new String(data, 0, length, "UTF-8");// 这个按照我们的应用层协议String engWord = request;Log.println("请求(英文单词):" + engWord);// 4. 执行业务(翻译服务),不是我们本次演示的重点String chiWord = translate(engWord);Log.println("翻译后的结果:" + chiWord);// 5. 按照应用层协议,封装响应String response = chiWord;// 进行字符集编码  String -> byte[]byte[] sendBuf = response.getBytes("UTF-8");// 6. 发送响应// 作为发送方需要提供DatagramPacket sentPacket = new DatagramPacket(sendBuf, 0, sendBuf.length,     // 要发送的数据socketAddress                         // 从请求信封中拆出来的对象的地址(ip + port));Log.println("准备好发送 DatagramPacket 并发送");socket.send(sentPacket);Log.println("发送成功");// 7. 本次请求-响应周期完成,继续下一次请求-响应周期}//        socket.close(); // 由于我们是死循环,这里永远不会走到}private static final HashMap<String, String> map = new HashMap<>();private static void initMap() {map.put("apple", "苹果");map.put("pear", "梨");map.put("orange", "橙子");}private static String translate(String engWord) {String chiWord = map.getOrDefault(engWord, "查无此单词");return chiWord;}
}
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;public class Log {public static void println(Object o) {LocalDateTime localDateTime = LocalDateTime.now(ZoneId.of("Asia/Shanghai"));DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");String now = formatter.format(localDateTime);String message = now + ": " + (o == null ? "null" : o.toString());System.out.println(message);}public static void main(String[] args) {println(1);}
}

TCP流套接字编程

基于TCP做的翻译服务
TCP:可靠、有连接、面向字节流

有连接:打电话(先拨号,拨通才能通信)
无连接:接发信(无脑发送,对方在不在都没关系)

ServerSocket API

ServerSocket 是创建TCP服务端Socket的API。
ServerSocket 构造方法:

服务器使用的TCP Socket对象(传入的端口,就是要公开的端口,一般称为监听(listen)端口)

ServerSocket 方法:

accept(接受):接起电话(服务器是电话铃响的这一方)

Socket对象:建立起的连接

socket代表的是一条连接
close():挂电话(谁都可以挂)

Socket API

Socket 是客户端Socket,或服务端中接收到客户端建立连接(accept方法)的请求后,返回的服务端Socket。
不管是客户端还是服务端Socket,都是双方建立连接以后,保存的对端信息,及用来与对方收发数据的。
Socket 构造方法:

服务器的Socket对象是从accept()中获取到的
所以,只有客户端的Socket对象需要手动实例化出来
这个构造方法是给客户端使用,传入服务器的ip + port(服务器的ip + port是公开的)

一旦socket对象拿到(双方是同时拿到的:电话接通是双方同时接通的),双方就地位平等了,只区分发送方/接收方即可。

Socket 方法:

面向数据报文和面向字节流

import com.xxx.net_demo.util.Log;import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
import java.util.HashMap;
import java.util.Scanner;public class TranslateServer {public static final int PORT = 8888;public static void main(String[] args) throws Exception {initMap();ServerSocket serverSocket = new ServerSocket(PORT);while (true) {// 接电话Log.println("等待对方来连接");Socket socket = serverSocket.accept();Log.println("有客户端连接上来了");// 对方信息:InetAddress inetAddress = socket.getInetAddress();  // ipLog.println("对方的 ip: " + inetAddress);int port = socket.getPort();    // portLog.println("对方的 port: " + port);SocketAddress remoteSocketAddress = socket.getRemoteSocketAddress();    // ip + portLog.println("对方的 ip + port: " + remoteSocketAddress);// 读取请求InputStream inputStream = socket.getInputStream();Scanner scanner = new Scanner(inputStream, "UTF-8");String request = scanner.nextLine();    // nextLine() 就会去掉换行符String engWord = request;Log.println("英文: " + engWord);// 翻译String chiWord = translate(engWord);Log.println("中文: " + engWord);// 发送响应String response = chiWord;  // TODO: 响应的单词中是没有 \r\nOutputStream outputStream = socket.getOutputStream();OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream, "UTF-8");PrintWriter writer = new PrintWriter(outputStreamWriter);Log.println("准备发送");writer.printf("%s\r\n", response);writer.flush();Log.println("发送成功");// 挂掉电话socket.close();Log.println("挂断电话");}
//        serverSocket.close();}private static final HashMap<String, String> map = new HashMap<>();private static void initMap() {map.put("apple", "苹果");map.put("pear", "梨");map.put("orange", "橙子");}private static String translate(String engWord) {String chiWord = map.getOrDefault(engWord, "查无此单词");return chiWord;}
}
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;public class Log {public static void println(Object o) {LocalDateTime localDateTime = LocalDateTime.now(ZoneId.of("Asia/Shanghai"));DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");String now = formatter.format(localDateTime);String message = now + ": " + (o == null ? "null" : o.toString());System.out.println(message);}public static void main(String[] args) {println(1);}
}

网络原理(2)——网络开发相关推荐

  1. 【网络原理】网络概述

    1.1.互联网概述 1.1.1.互联网概述→Internet 1.网络:由若干结点和连接这些结点的链路组成: 2.结点:可以是计算机.集线器.交换机.路由器等: 3:网络与互联网之间的关系→网络计算机 ...

  2. 网络原理(Java网络编程)

    1.局域网和广域网 局域网LAN: 即 Local Area Network,简称LAN. 局域网内的主机之间能方便的进行网络通信,又称为内网;局域网和局域网之间在没有连接的情况下,是无法通信的. 局 ...

  3. JavaEE初阶---网络原理初识+网络编程套接字+网络原理之TCP_IP

  4. JavaEE——网络原理_应用层

    JavaEE传送门 JavaEE JavaEE--No.1 套接字编程(UDP) JavaEE--No.2 套接字编程(TCP) 目录 网络原理 应用层 网络原理 介绍 TCP/IP 协议中每一层里面 ...

  5. 无线网络原理知识总结

    无线网络原理 无线网络传输技术 WLAN的MAC层关键技术 WLAN的组建 IEEE802.11协议 WLAN的勘测与规划 WLAN的安装与部署 蓝牙技术与组网 无线MESH技术 MANET路由协议 ...

  6. 网站的工作原理:网络开发新手(或任何人)入门

    网站的工作原理:网络开发新手(或任何人)入门 如果您刚接触Web开发,您认为自己知道网络的工作原理 - 至少在基本层面上. ...但是,当您尝试解释一个网站为什么出现空白. 什么是IP地址? &quo ...

  7. 越来越多的岗位需要DPDK,那从DPDK该如何提升网络底层效率丨网络原理丨Linux服务器开发丨后端开发丨网络底层原理

    越来越多的岗位需要dpdk,那从dpdk该如何提升网络底层效率 1. dpdk线程模型 2. kni与数据接收处理流程 3. 手把手代码实现 视频讲解如下,点击观看: 越来越多的岗位需要DPDK,那从 ...

  8. MOOC网深度学习应用开发5——生成式对抗网络原理及Tensorflow实现

    生成式对抗网络原理及Tensorflow实现 生成式对抗网络GAN的简介 利用GAN生成Fashion-MNIST图像 鸢尾花品种识别:TensorFlow.js应用开发 TensorFlow.js介 ...

  9. 基于以太坊网络的智能合约开发、部署和测试(入门)

    为什么80%的码农都做不了架构师?>>>    基本概念: 以太坊是一个开放的.公开的区块链平台,允许用户构建自己的去中心化应用在上面运行 Solidity是一种语法类似JavaSc ...

  10. 网络原理往期考试题+部分详解+最终版

    一.填空题: (+号代表出现次数,无则说明一次) ++1. 在采用电信号表达数据的系统中,数据有数字数据和__模拟数据__两种. 2. 国际标准化组织ISO提出的不基于特定机型.操作系统或公司的网络体 ...

最新文章

  1. bzoj3295:[CQOI2011]动态逆序对
  2. hdu6438 Buy and Resell 买卖物品 ccpc网络赛 贪心
  3. 【tomcat】手动部署动态JavaWeb项目到tomcat
  4. P2514-[HAOI2010]工厂选址【贪心】
  5. 《老子》中国古代先秦诸子百家经典欣赏
  6. 第一:Python操作MySQL数据库
  7. Matlab读取TXT文本文件通用程序
  8. 学生宿舍管理系统——UML 2nd
  9. 单片机知识点总结框图_89C51单片机的结构框图及原理解析
  10. windows查看局域网内所有已使用的IP
  11. 雅思考试流程、需要具体注意些什么、怎么复习?
  12. 网页聊天室php无数据库_无需数据库的PHP聊天室程序
  13. C3: 基金名称末尾 A 和 C 的区别
  14. 米家扫地机器人 设置不停止_【小米 米家 扫地机器人使用总结】设置|清扫_摘要频道_什么值得买...
  15. 单片机c语言程序编写步骤,Proteus运行Keil编写的51单片机C语言步骤
  16. 人脸识别技术及其各种用例
  17. 竹云+巨杉丨互信认证 安全可靠
  18. 【软件工程】------软件开发
  19. 什么是受管制的代码?什么是托管代码?
  20. Vue实现吸顶的效果

热门文章

  1. python语言应用智慧树答案_智慧树Python语言应用答案全部
  2. 精致的利己主义者之论,转自知乎
  3. 转义符——反斜杠(\)
  4. 数据库TPCC benchmark测试工具对比
  5. 线条边框简笔画图片大全_爱牙日手抄报 手抄报作业大全 模板边框设计
  6. 【我的黑名单】优酷的道德水准之低再次突破我的底线,制片王某剽窃19岁少年创意,陌陌科技也不是什么好鸟
  7. 【统计学】详解 A/B 测试
  8. yan-master项目集成Activiti 6.0.0
  9. 分布式ID雪花算法-解析
  10. php格式转换成docx,如何在PHP中修改.doc或.docx文件