1.网络通信要素概述
IP地址和端口号/网络通信协议2.网络通信协议(以TCP/IP模型为例)
常用网络通信协议:TCP/IP协议、IPX/SPX协议、NetBEUI协议等。
****国际标准****
TCP/IP,即Transmission Control Protocol/Internet Protocol的简写
中译名为传输控制协议/因特网互联协议,是Internet最基本的协议、Internet国际互联网络的基础。
3.IP地址和端口号(组合就是网络套接字)
URL url = new URL("文件的地址");
3.1 IP 地址:InetAddress(在Java中使用InetAddress类代表IP)3.2 端口号
端口号就是标识正在计算机上运行的进程(程序)
不同的进程有不同的端口号
被规定为一个 16 位的整数 0~65535。
4.TCP|IP模型中的传输层2个重要的协议:TCP协议和UDP协议
5.TCP协议详解
(1)使用TCP协议前,须先建立TCP连接,形成传输数据通道(2) 传输前,采用“三次握手”方式,点对点通信,是可靠的。四次挥手
(3) TCP协议进行通信的两个应用进程:客户端、服务端。
(4) 在连接中可进行大数据量的传输
(5) 传输完毕,需释放已建立的连接,效率低
6.UDP协议详解(无连接)
(1)将数据、源、目的封装成数据包,不需要建立连接(2) 每个数据报的大小限制在64K内(以容器的形式进行发送)
(3) 发送不管对方是否准备好,接收方收到也不确认,故是不可靠的
(4) 可以广播发送
(5) 发送数据结束时无需释放资源,开销小,速度快
发送方 接受方
DatagramSocket----比作发送方 比作接收方
DatagramPacket-----数据打包对象
7.TCP网络编程
基于Socket套接字实现服务端与客户端对话
8.UDP网络编程
8.1 UDP网络通信
UDP没有服务器与客户端这样的说法。
发送方和接收方
a.类 DatagramSocket 和 DatagramPacket 实现了基于 UDP 协议网络程序。
b.UDP数据报通过数据报套接字 DatagramSocket 发送和接收,系统不保证 UDP数据报一定能够安全送到目的地,也不能确定什么时候可以抵达。
c.DatagramPacket 对象封装了UDP数据报,在数据报中包含了发送端的IP地址和端口号以及接收端的IP地址和端口号。
d.UDP协议中每个数据报都给出了完整的地址信息,因此无须建立发送方和接收方的连接。如同发快递包裹一样。
8.2 UDP网络通信流程1、DatagramSocket与DatagramPacket
2、建立发送端,接收端
3、建立数据包
4、调用Socket的发送、接收方法
5、关闭Socket注意:发送端与接收端是两个独立的运行程序
8.3 有单播,多播,广播的功能
UDP 不止支持一对一的传输方式,同样支持一对多,多对多,多对一的方式,也就是说 UDP 提供了单播,多播,广播的功能。
8.4 单播
是指封包在计算机网络的传输中,目的地址为单一目标的一种传输方式。
【你对小月月喊“小月月”,那么只有小月月回过头来答应你。】8.5 广播
是指封包在计算机网络中传输时,目的地址为网络中所有设备的一种传输方式。实际上,这里所说的“所有设备”也是限定在一个范围之中,称为“广播域”。
255.255.255.255
【你在公司大喊一声“放假了”, 全部同事都会响应,大叫爽死了。】8.6 组播
也叫多播, 多点广播或群播。 指把信息同时传递给一组目的地址。它使用策略是最高效的,因为消息在每条网络链路上只需传递一次,而且只有在链路分叉的时候,消息才会被复制。多播组通过 D 类 IP 地址和标准 UDP 端口号指定。D 类 IP 地址在 224.0.0.0 和 239.255.255.255 的范围内(包括两者)。地址 224.0.0.0 被保留,不应使用。
【你在大街上大喊一声“美女”, 会有一群女性回头看你。】
发送的IP地址:238.222.111.0
接收方:
MulticastSocket ms=new MulticastSocket(4399);
/* 加入那个组? */
ms.joinGroup(InetAddress.getByName("238.222.111.0"));
byte[] bs=new byte[100];
DatagramPacket dp=new DatagramPacket(bs, bs.length);
ms.receive(dp);
System.out.println(new String(bs).trim());
/* 离开小组 */
ms.leaveGroup(InetAddress.getByName("238.222.111.0"));
ms.close();===================================================================================================
udp:数据报文(包)协议
DatagramPacket====传输层
=====UDP
DatagramSocket====传输层
有三种:
单播:是指只向一个固定的机器发送包
广播:是向255.255.255.255发送,所有监听某端口的机器都可以接收到
组播:是向一个用户组发送,该组里面所有用户可以接收到
DatagramPacket有2个作用
1.发送的包===>要给定发送的内容以及发送的地址与端口
DatagramPacket dp =
new DatagramPacket(byte[],0,length,InetAddress,port);
2.接收的包===>只要指定接收包的大小
DatagramPacket dp =
new DatagramPacket(byte[],0,length);DatagramSocket有2个作用
1.发送的人===>只需要new出来就可以了
DatagramSocket ds = new DatagramSocket();
2.接收的人===>需要指定接收的地址以及端口
DatagramSocket ds = new DatagramSocket(port,InetAddress);对于三种udp协议
1.发送方完全相同,单播是指定一个ip
广播是指定255.255.255.255这个ip
组播是指定D类ip(224-239)
2.接收方单播直接指定一个ip与端口
广播不能指定ip,只要端口
组播要使用MulticastSocket,
然后使用joinGroup加入该组
DatagramSocket创建接收端的使用
发送端
package com.zking.test02;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
//发送方
public class FileSender {
public static void main(String[] args) throws Exception{
System.out.println("---------发送端-----------");
DatagramSocket ds = new DatagramSocket();
System.out.println("发送端已开启");
//发送一个文件
File file = new File("D:\\1.jpg");
//字节
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
DatagramPacket dp = null;
//每次读取一个字节数组(10个单位)----立刻通过数据报 进行打包发送
byte[] buf = new byte[1024];
int len = 0;
int count = 0;
while(-1!=(len = bis.read(buf))) {
//创建数据报对象 将每次读取的字节数组进行打包
dp = new DatagramPacket(buf, buf.length, InetAddress.getByName("127.0.0.1"), 8989);
//发送
ds.send(dp);
count+=10;
// Thread.sleep(50);
System.out.println(count);
}
//发送一个特定的表示
dp = new DatagramPacket("xb".getBytes(), "xb".getBytes().length, InetAddress.getByName("127.0.0.1"), 8989);
ds.send(dp);
ds.close();
System.out.println("发送完毕!!!");
//sb
//单播 组播 广播
}
}
接受端
package com.zking.test02;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
//接收端
public class FileReceive {
public static void main(String[] args) throws Exception{
System.out.println("---------接收端-----------");
DatagramSocket ds = new DatagramSocket(8989);
System.out.println("接收端已开启");
DatagramPacket dp = null;
byte[] buf = new byte[1024];
//创建输出流
File file = new File("D:\\Zking\\美女.jpg");
FileOutputStream fos = new FileOutputStream(file);
BufferedOutputStream bos = new BufferedOutputStream(fos);
while(true) {
dp = new DatagramPacket(buf, buf.length);//接收数据包
//调用接收激活的方法
ds.receive(dp);
byte[] data = dp.getData();
int n = dp.getLength();
if("xb".equals(new String(data,0,n))) {
System.out.println("接收完毕");
break;
}
//写入本地文件
bos.write(buf);
bos.flush();
}
//关闭
bos.close();
fos.close();
ds.close();
}
}
Map集合的使用!
package com.zking.test03;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
public class Demo_03 {
public static void main(String[] args) {
// Collection集合
// 单列集合--一次只能存储一个数据
// List|Set
// List:有序 元素可重复
// ArrayList|LinkedList|Vector
// Set:无序 唯一
// HashSet
// List<String> list = new ArrayList<String>();
//
// list.add("agds");
// size()
// clear
// get
// contains
// isEmpty
// remove
// List<String> list = new ArrayList<String>();
// list.add("agds1");
// list.add("agds2");
// list.add("agds4");
// list.add("agds3");
// list.add("agds5");
// list.add("agds6");
// for (int i = 0; i < list.size(); i++) {
// System.out.println(list.get(i));
// }
// for (String string : list) {
// System.out.println(string);
// }
// //迭代器的方式
// Iterator<String> iterator = list.iterator();
// while(iterator.hasNext()) {
// System.out.println(iterator.next());
// }
//Map集合:双列集合 新增 ----一次可以加2个数据
//存储数据是以键值对的形式进行存储.
//键是唯一 值可以重复
//常用的实现类 HashMap
//创建一个Map集合
// Map map = new HashMap();
//
// //新增
// map.put("杨过", "小笼包");
// map.put("彭勇", "翠花");
// map.put("老王", "熊妹");
// map.put("唐烨", "王寡妇");
// map.put("瑜伽", "王寡妇");
// //大小
// System.out.println(map.size());//5
//clear清空
// map.clear();
// System.out.println(map.size());
//判断集合是否为空
// System.out.println(map.isEmpty());
//获取所有的值
// Collection values = map.values();
// for (Object object : values) {
// System.out.println(object);
// }
//获取所有的键
// Set keySet = map.keySet();
// for (Object object : keySet) {
// System.out.println(object);
// }
// 根据键获取值
// Object object = map.get("瑜伽");
// System.out.println(object);
//
//
// //需求:对map进行遍历 同时输出所有的键和值 一一对应
// Set keySet = map.keySet();//得到所有的键
// for (Object object2 : keySet) {
// //根据键获取对应的值
// Object object3 = map.get(object2);
// System.out.println(object2+"---"+object3);
// }
//坚决不使用
//Entry实体+迭代器
//1.将Map集合中的每一对键值对封装成Entry实体对象,将键和值作为它的属性
//2.将Entry转换成迭代器再次遍历
// Map<String,String> map = new HashMap<String,String>();
// //新增
// map.put("杨过", "小笼包");
// map.put("彭勇", "翠花");
// map.put("老王", "熊妹");
// map.put("唐烨", "王寡妇");
// map.put("瑜伽", "王寡妇");
//
// //map集合调用entrySet方法将map集合中的键值对封装成Entry实体对象返回Set集合
// Set<Entry<String, String>> entrySet = map.entrySet();
// //set通过迭代器遍历
// Iterator<Entry<String, String>> iterator = entrySet.iterator();
// while(iterator.hasNext()) {
// Entry<String, String> next = iterator.next();
// System.out.println(next.getKey()+"--"+next.getValue());
// }
//Map集合中的存储类型
//没有指定泛型 默认Object
Student stu = new Student(123, "asd");
Student stu3 = new Student("123", "asd");
//int
Student<Integer> stu2 = new Student<Integer>(1, "123");
//String
Student<String> stu4 = new Student<String>("123", "123");
//恐怖
// Map<List<Student<String>>,List<List<String>>> map = new
// HashMap<List<Student<String>>, List<List<String>>>();
//开了一间监狱 有10间房(监狱1234) 每间房有20个犯人
//Map模拟一键生成 打印输出所有房间的犯人
Map<String,List<FanRen>> map = new HashMap<String,List<FanRen>>();
//循环模拟10间房间
for (int i = 1; i <= 10; i++) {
//每间房有20个犯人
List<FanRen> list = new ArrayList<FanRen>();
for (int j = 1; j <= 20; j++) {
list.add(new FanRen(j+1, "张三"+j));
}
//生成的10间放 以及每间房20个人一起加入Map集合
map.put("监狱"+i+"号", list);
}
//遍历
Set<Entry<String, List<FanRen>>> entrySet = map.entrySet();
//迭代器
Iterator<Entry<String, List<FanRen>>> its = entrySet.iterator();
while(its.hasNext()) {
Entry<String, List<FanRen>> next = its.next();
String key = next.getKey();//键
System.out.println(key);
//获取值
List<FanRen> value = next.getValue();
for (FanRen fanRen : value) {
System.out.println("\t"+fanRen);
}
}
}
}