## 概述
地球村, 网络让距离变近。
计算机网络:计算机网络是将**地理位置不同**的具有独立功能的**多台计算机及其外部设备,通过通信线路(有线或者无线)连接起来**,在网络操作系统,网络管理软件及**网络通信协议**的管理和协调下,**实现资源共享**和信息传递的计算机系统
网络编程的目的:
电台,无线电台,,,传播交流信息,数据交换,通信
怎么做
1.如何准确定位网络上的一台主机 :端口,定位到计算机上的某个资源
2.找到了这个主机,如何传输数据?
3.javaweb:网页编程 B/S架构,通过浏览器去架构的
网络编程:TCP/IP() C/S架构
1.网络编程中有两个主要的问题
如何准确的定位到网络上的一台或者多台主机
找到主机之后如何进行通信
### 2.网络编程中的要素
IP和端口号 IP.
网络通信协议 udp,tcp
3.万物皆对象
## IP
IP地址:Inetaddress
唯一定位一台网络上计算机
127.0.0.1:本机LocalHOST
IP地址的分类
![](D:\jpp\图片\Pictures\代码截图\Screenshot_2021-09-30-21-55-59-970_tv.danmaku.bili (3).jpg)
![](D:\jpp\图片\Pictures\代码截图\屏幕截图 2021-10-09 230012.png)
ipv4/ipv6
IPV4 127.0.0.1 ,四个字节组成。 , 0~255, 42亿~;
IPV6 128位。8个无符号整数0~9,a~e,
2001:aaab:aaaa:0015:0000:0012:1aaa:1314
公网(互联网) 私网(局域网)
192.168.xx.xx专门给组织内部使用
ABCD类地址
###### IP地址的分类 abcde类是如何划分的
>根据网络的标识长度进行区分,A类为8位、B类为16位、C类为24位、D类位多播地址。
>
>IP地址中的A、B、C、D类分别是:
>
>1、A类:在IP地址的四段号码中,第一段号码为网络号码,剩下的三段号码为本地计算机的号码。
>
>A类IP地址中网络的标识长度为8位,主机标识的长度为24位,A类网络地址数量较少,有126个网络,每个网络可以容纳主机数达1600多万台。
>
>A类IP地址的地址范围是1.0.0.0到127.255.255.255(二进制表示为:00000001 00000000 00000000 00000000 - 01111111 11111111 11111111 11111111)。最后一个是广播地址。
>
>A类IP地址的子网掩码为255.0.0.0,每个网络支持的最大主机数为256的3次方-2=16777214台。
>
>2、B类:在IP地址的四段号码中,前两段号码为网络号码。
>
>B类IP地址中网络的标识长度为16位,主机标识的长度为16位,B类网络地址适用于中等规模的网络,有16384个网络,每个网络所能容纳的计算机数为6万多台。
>
>B类IP地址地址范围128.0.0.0-191.255.255.255(二进制表示为:10000000 00000000 00000000 00000000----10111111 11111111 11111111 11111111)。 最后一个是广播地址。
>
>B类IP地址的子网掩码为255.255.0.0,每个网络支持的最大主机数为256的2次方-2=65534台。
>
>3、C类:在IP地址的四段号码中,前三段号码为网络号码,剩下的一段号码为本地计算机的号码。
>
>C类IP地址中网络的标识长度为24位,主机标识的长度为8位,C类网络地址数量较多,有209万余个网络。适用于小规模的局域网络,每个网络最多只能包含254台计算机。
>
>C类IP地址范围192.0.0.0-223.255.255.255(二进制表示为: 11000000 00000000 00000000 00000000 - 11011111 11111111 11111111 11111111)。
>
>C类IP地址的子网掩码为255.255.255.0,每个网络支持的最大主机数为256-2=254台
>
>4、D类:D类IP地址在历史上被叫做多播地址(multicast address),即组播地址。在以太网中,多播地址命名了一组应该在这个网络中应用接收到一个分组的站点。
>
>多播地址的最高位必须是“1110”,范围从224.0.0.0到239.255.255.255。
>
>
>
>
>扩展资料:
>
>特殊的IP地址:
>
>1、每一个字节都为0的地址(“0.0.0.0”)对应于当前主机;
>
>2、IP地址中的每一个字节都为1的IP地址(“255.255.255.255”)是当前子网的广播地址;
>
>3、IP地址中凡是以“11110”开头的E类IP地址都保留用于将来和实验使用。
>
>
ip没有构造,也没有方法
intAddress类
``
```
package com.JP.ip01;
import java.net.InetAddress;
import java.net.UnknownHostException;
//测试IP
public class Test {
public static void main(String[] args) {
try {
//查询本机地址方法一
InetAddress inetAddress01=InetAddress.getByName("127.0.0.1");
System.out.println(inetAddress01);
//方法二
System.out.println("localhost");
//方法三
InetAddress inetAddress03=InetAddress.getLocalHost();
//查询网站IP地址
InetAddress inetAddress02=InetAddress.getByName("www.baidu.com");
System.out.println(inetAddress02);
//常用方法
//
//System.out.println(inetAddress02.getAddress());
System.out.println(inetAddress02.isAnyLocalAddress());
//System.out.println(inetAddress02.getCanonicalHostName());
//获得IP
System.out.println(inetAddress02.getHostAddress());
//域名,或者自己电脑的名字
System.out.println(inetAddress02.getHostName());
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
}
```
## 端口
端口表示计算机上的一个程序的进程
(一栋楼是一个IP,每户人家是一个具体的IP端口号,通过一个号才可以进家里做事,而电脑上的资源就像家里的小物件)
不同的进程有不同的端口号,用来区分软件
端口被规定0到65535
TCP端口, UDP端口:65535*2,单个协议下,端口号不能冲突
常见端口分类
- 共有端口0~1023端口
HTTP:80端口
HTTPS:443端口
FTP:21端口
Telent:23端口
程序注册端口:1024~49151,分配给用户或者程序
Tomcat 8080
MySQL:3306
Oracle:1521
动态端口,私有端口:49152~65535
netstat -ano 查看电脑上的所有端口
netstat -ano|findstr"5900" 查看5900端口在做的事,即查看指定端口
tasklist|finder"8696" 查看指定端口的进程
Ctrl+shift+Esc :打开任务管理器
![](D:\jpp\图片\Pictures\代码截图\屏幕截图 2021-10-09 175218.png)
IntSocketAddress 类
```
package com.JP.ip01;
import java.net.InetSocketAddress;
public class TestInetSocketAddress {
public static void main(String[] args) {
//输出IP加上端口号
InetSocketAddress socketAddress01=new InetSocketAddress("127.0.0.1",8080);
System.out.println(socketAddress01);
//输出名字加IP加端口号
InetSocketAddress socketAddress02=new InetSocketAddress("localhost",8080);
System.out.println(socketAddress02);
System.out.println(socketAddress01.getAddress());
//返回地址
System.out.println(socketAddress01.getHostName());
//返回端口号
System.out.println(socketAddress01.getPort());
}
}
```
## 通信协议
- 协议:约定,好比我们现在说的普通话
- ###### 网络通信协议·:速率,传输码率,代码结构,传输控制...
- 问题:非常复杂,
- 大事化小:分层
- ##### TCP/IP协议簇:实际上是一组协议
- 重要:
- TCP:用户传输协议
- UDP:用户数据报协议
- 出名的协议:
- TCP:
- IP:网络互连协议
![](D:\jpp\图片\Pictures\代码截图\Screenshot_2021-09-30-21-55-59-970_tv.danmaku.bili (3).jpg)
###### YCP udp对比
TCP:打电话
- 链接,稳定
- 三次握手,四次挥手
```
最少需要三次,保证稳定连接
A:你瞅啥?(试图交流,看有没有回应)
B:瞅你咋滴?(有回应后,B会再确定一遍A在不在)
A:干一场!(A回应B)
分开
A:我要断开了(告诉B要断开了)
B:我知道你要断开了(B已经知道A要断开了,但不确定他是否断开)
B:你真的断开了吗(B再询问一次)
A:我真的要断开了(A回应)
```
- 客户端,服务端
- 传输完成,释放连接,效率低
UDP:发短信
- 不连接,不稳定
- 客户端,服务端:没有明确界限
- 不管有没有准备好,都可以发给你
- 导弹
- DDOS:洪水攻击(饱和攻击)
## TCP
客户端
1.连接服务器Socket
2.发送消息
```
```
```
package desson02;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
//客户端
public class TCPClientDemo01 {
public static void main(String[] args) {
//1 要知道服务器地址(见服务端),端口号
Socket socket01=null;
OutputStream os01=null;
try {
InetAddress serverIP01 = InetAddress.getByName("127.0.0.1");
int port=9999;
//2 创建一个socket连接
socket01 = new Socket(serverIP01,port);//默认无参,但它是有参的
//发送消息 I/O流
os01 = socket01.getOutputStream();//流出去了,往哪个地方流,我们要写
os01.write("你好,江大萍".getBytes());
//发送完了,等服务端接收
} catch (Exception e) {
e.printStackTrace();
}finally {
//客户端也要关闭资源
if (os01!=null) {
try {
os01.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket01!=null) {
try {
socket01.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
```
服务端
1. 建立服务的端口ServerSocket
2. 等待用户的连接accept
3. 接收用户的消息(关闭资源是先写后关)
```
```
```
package desson02;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
//服务端
public class TCPserverDemo01 {
public static void main(String[] args) {
//1.我的有一个地址
ServerSocket serverSocket01=null;
Socket socket=null;
InputStream is01=null;
ByteArrayOutputStream baos=null;
try {
serverSocket01 = new ServerSocket(9999);//socket是插槽的意思
//现在这个地址就是LocalHost9999,客户端就要连这个地址
//2.需要开启一个服务端的插槽,要开启,就要传参数
//3.等待客户端连接过来
socket = serverSocket01.accept();//这个Socket就是客户端的Socket
//通过.accept方法监听到了之后就说明已经建立成功了,都是同一个对象,不过是在不同的类里面
//4.读取客户端的消息
is01 = socket.getInputStream();
/*
*/
//5.管道流(把输入流通过管道接一下再输出去)
baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len= is01.read(buffer))!=-1){
baos.write(buffer,0,len);
}
System.out.println(baos.toString());
} catch (IOException e) {
e.printStackTrace();
}finally {
//6.关闭资源,要一个一个按照顺序关
if (baos!=null) {
try {
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (is01!=null) {
try {
is01.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket!=null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (serverSocket01!=null) {
try {
serverSocket01.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
```
##### 文件上传
文件上传就是读取,再把它变成一个流再把它传出去
客户端
```
//客户端
package desson02;
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
public class TCPClientDemo02 {
public static void main(String[] args) throws Exception {
//1.创建一个Socket连接
Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 9000);
//2.创建一个输出流
OutputStream os = socket.getOutputStream();
//3.文件流,读取文件
FileInputStream fis = new FileInputStream(new File("QQ图片20210920213012.jpg"));
//4.写出文件
byte[] buffer = new byte[1024];
int len;
while ((len=fis.read(buffer))!=-1){
os.write(buffer,0,len);
}
//通知服务器,我已经结束了
socket.shutdownOutput();//我已经传输完了
//确定服务器接收完毕才可以断开连接
InputStream inputStream = socket.getInputStream();
//String byte[]
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer2 = new byte[2014];
int len2;
len2=inputStream.read(buffer2);
while (len2!=-1){
//输出
baos.write(buffer2,0,len2);
}
System.out.println(baos.toString());
//5.关闭资源
baos.close();
inputStream.close();
fis.close();
os.close();
socket.close();
}
}
```
服务端
```
//服务端
package desson02;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;
public class TCPServerDemo02 {
public static void main(String[] args)throws Exception {
//1.建服务端口
ServerSocket serverSocket = new ServerSocket(9000);
//2.监听客户端的连接,客户端没连过来它是不会停的
Socket socket = serverSocket.accept();//阻塞式监听,会一直等待客户端连接
//获取输入流
InputStream is = socket.getInputStream();
//文件输出
//加一个管道输出流
FileOutputStream fos = new FileOutputStream(new File("receive2.jpg"));
byte[] buffer = new byte[1024];
int len;
len=is.read(buffer);
while (len!=-1){
fos.write(buffer,0,len);
}
//通知客户端我接收完毕了
OutputStream outputStream = socket.getOutputStream();
outputStream.write("我接受完毕了,你可以断开了".getBytes(StandardCharsets.UTF_8));
//关闭资源
fos.close();
is.close();
socket.close();
}
}
```
##### Tomcat
C/S
服务端
- 自定义S
- Tomcat服务器S:JAVA后台开发
客户端
- 自定义C
- 浏览器B
## UDP
不用连接,但要知道对方的地址
涉及到两个类
Class DatagramPacket,发送包(不需要建立连接)
发送端
```java
package Lesson03;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.nio.charset.StandardCharsets;
//不需要连接服务器
public class UDpClientDemo01 {
public static void main(String[] args) throws Exception{
//1.建立一个包Socket
DatagramSocket socket = new DatagramSocket();
//2.建个包
String msg="hello,服务器!";
//要有一个发送的人,发送给谁
InetAddress localhost = InetAddress.getByName("localhost");//返回一个当前地址
int port=9090;
//下面五个数据的解释:数据,数据的长度起始,要发送给谁
DatagramPacket packet = new DatagramPacket(msg.getBytes(), 0, msg.getBytes().length);
//变成一个字节数组,从哪里开始,到哪里结束
//3.发送包
socket.send(packet);//有个方法send,这个包需要参数
//关闭流
socket.close();
}
}
```
```
```
接收端
```
package Lesson03;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
//还是要等待客户端地连接
public class UdpServerDemo01 {
public static void main(String[] args)throws Exception {
//开放端口
DatagramSocket socket = new DatagramSocket(9090);
//接收数据 接收包
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);//要从哪里去接//接收
socket.receive(packet);//阻塞接收
System.out.println(packet.getAddress().getHostAddress());
new String(packet.getData(),0, packet.getLength()).
//关闭连接
socket.close();
//最终结果,服务器接收到消息并停止
//127.0.0.1
//hello,服务器!
}
}
```
他们没有所谓的客户端和服务端,可以收到消息,也有对方的IP封装在里面,(每个地方都可以有对应的端口号,都可以发送消息或者接收消息)无线连接,没有建立的,YCP必须要建立一个服务器,可能很多都可以连到那个服务器进行操作
##### 咨询
发送
```
```
```
package chart;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
public class UdpSanderDamo01 {
public static void main(String[] args) throws Exception {
DatagramSocket socket = new DatagramSocket(8888);//1.
//DatagramPacket packet = new DatagramPacket();
// 3.(从上一行代码)此时发现Packet需要数据,所以我们要准备数据
//4.准备数据:控制台读取 System.in,其中System.in可以用包装流包装起来
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
//可以用BufferedReader读过来,从哪里开始读呢?
//从InputStreamReader,从我们的控制台读,读我们的System.in
//到最后就把控制台的消息读出来变成了我们的bufferedReader数据
//接收完了就要用包裹把它发送出去,利用reader的readerLine()方法读取这一行
String data = reader.readLine();
//把data转换成数据,此时byte就有具体的数据了,我们命名为datas(数据不可读我们要转换成字节)
byte[] datas = data.getBytes();
DatagramPacket packet = new DatagramPacket(datas, 0, datas.length, new InetSocketAddress("localhost", 6666));
//具体的IP加端口号
socket.send(packet);//2. socket是为了发送消息,send需要一个Packet,此时需要重新new一个DatagramPacket
socket.close();
}
}
}
```
```
```
```
package chart;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class udpReserseDamo01 {
public static void main(String[] args) throws Exception {
DatagramSocket socket = new DatagramSocket(6666);//和那边一样的
byte[] container = new byte[1024];
while (true) {
DatagramPacket packet = new DatagramPacket(container, 0, container.length);//此此时这个packet需要一个地方去放它
//准备接收的包裹//byte[] container = new byte[1024];//准备接收包,把它放在DaregramPacket上面
//断开连接bye,要读数组
byte[] data = packet.getData();
String receivedatas = new String(data, 0, data.length);//这是我们接收的数据
if (receivedatas.equals("bye")){
break;
}
socket.receive(packet);//socket需要接收
// 阻塞式接收包裹,让它循环接收,在上面加一个while(true)
}
socket.close();
}
}
```