Java基础学习
- 一、 网络编程
 - 1.1 什么是网络编程
 - 1.2 常见的软件架构:
 - 1.3 网络编程的三要素
 - 1.4 IP
 - 1.4.1 InetAddress用法
 
- 1.5 端口号
 - 1.6 协议
 - 1.6.1 UDP协议
 - 1.6.1.1 UDP的三种通信方式
 
- 1.6.2 TCP协议
 - 1.6.2.1 TCP底层原理
 
一、 网络编程
1.1 什么是网络编程
解释:
在网络通信协议下,不同计算机上运行的程序,进行的数据传输
应用场景:即时通信、网游对战、金融证券、国际贸易、邮件、等等不管是什么场景,都是计算机跟计算机之间通过网络进行数据传输
- Java中可以使用
java.net包下的技术轻松开发出常见的网络应用程序 
1.2 常见的软件架构:
- cs —>
Client/Server

 - bs: 
Browser/Server

BS架构的优缺点: 
- 不需要开发客户端,只需要页面+服务端
 - 用户不需要下载,打开浏览器就能使用
 - 如果应用过大,用户体验受到影响
 
可能会导致游戏加载不出来
CS架构的优缺点:
- 画面可以做的非常精美,用户体验好
 - 需要开发客户端,也需要开发服务端
 - 用户需要下载和更新的时候太麻烦
 
CS:适合定制专业化的办公类软件如: IDEA、网游
 BS:适合移动互联网应用,可以在任何地方随时访问的系统
1.3 网络编程的三要素
IP
- 设备在网络中的地址,是唯一的标识。
 
端口号
- 应用程序在设备中唯一的标识。
 
协议
- 数据在网络中传输的规则,常见的协议有UDP、TCP、http、https、ftp。
 
1.4 IP
全称:Internet Protocol,是互联网协议地址,也称IP地址是分配给上网设备的数字标签
”说人话:“
 上网设备在网络中的地址,是唯一的
IPv4
全称:Internet Protocolversion 4,互联网通信协议第四版。采用32位地址长度,分成4组
由于太少IP值,现在又出现了IPv6
IPv6
- 全称:Internet Protocol version6 ,互联网通信协议第六版
 - 由于互联网的蓬勃发展,IP地址的需求量愈来愈大,而IPv4的模式下IP的总数是有限的,采用128位地址长度,分成8组
 
2.IPv4有什么特点
 目前的主流方案最多只有2^32次方个ip,目前已经用完了
 3.IPv6有什么特点
 为了解决IPv4不够用而出现的最多有2^128次方个ip可以为地球上的每一粒沙子都设定ip
lPv4的地址分类形式
- 公网地址(万维网使用)和私有地址(局域网使用)。
 192.168.开头的就是私有址址,范围即为192.168.0.0–192.168.255.255,专门为组织机构内部使用,以此节省IP
特殊IP地址
127.0.0.1,也可以是localhost:是回送地址也称本地回环地址,也称本机IP,永远只会寻找当前所在本机。
常用的CMD命令
 ipconfig: 查看本机IP地址
 ping:检查网络是否连通
1.4.1 InetAddress用法
| 用法 | 使用说明 | 
|---|---|
| static InetAddress getByName(String host) | 确定主机名称的IP地址。主机名称可以是机器名称,也可以是IP地址 | 
| String getHostName() | 获取此IP地址的主机名 | 
| String getHostAddress() | 返回文本显示中的IP地址字符串 | 
package Mysocketnet.MyInetAddressDom;
import java.net.InetAddress;
import java.net.UnknownHostException;
public class Dom1 {
    public static void main(String[] args) throws UnknownHostException {
        //获取到InetAddress对象
        InetAddress address = InetAddress.getByName("lzqxiaojiaoqi");
        System.out.println(address);
        //获取电脑名字
        String hostName = address.getHostName();
        System.out.println(hostName);//lzqxiaojiaoqi
        //获取IP地址
        String ip = address.getHostAddress();
        System.out.println(ip);//10.200.27.49
    }
}
 
1.5 端口号
应用程序在设备中唯一的标识。
 端口号:
- 由两个字节表示的整数,取值范围:0~ 65535
 - 其中0~1023之间的端口号用于一些知名的网络服务或者应用
 - 我们自己使用1024以上的端口号就可以了
 
注意:一个端口号只能被一个应用程序使用

1.6 协议
TCP/IP 模型:
 
1.6.1 UDP协议
特点:
- 用户数据报协议(User Datagram Protocol)
 - UDP是面向无连接通信协议。
速度快,有大小限制一次最多发送64K,数据不安全,易丢失数据 
由于会缺失数据,传输快,主要应用于语音通话、看视频、网络会议等等
UDP通信程序(发送数据):
-  
找快递公司 ---->
创建发送端的DatagramSocket对象 -  
打包礼物 ---->
数据打包(DatagramPacket) -  
快递公司发送包裹 ---->
发送数据 -  
付钱走人 ---->
释放资源 
package Mysocketnet.MyUDP;
import java.io.IOException;
import java.net.*;
public class SendMessageDom {
    public static void main(String[] args) throws IOException {
        //创建DatagramSocket(快递公司)
        DatagramSocket ds = new DatagramSocket();
        //打包数据(DatagramPacket)
        //首先创建需要传输的数据,变成byte[]传输
        String str = "Hello World !!";
        byte[] bytes = str.getBytes();
        int port = 10086;
        InetAddress address = InetAddress.getByName("127.0.0.1");
        //参数:1. 需要传输的数据byte[],2.截取的长度,3. id值,4. 端口
        DatagramPacket packet = new DatagramPacket(bytes, bytes.length, address, port);
        //发送数据(包裹)
        ds.send(packet);
    //清理资源
        ds.close();
    }
}
 
UDP通信程序(接收数据):
- 找快递公司 -----> 
创建接收端的DatagramSocket对象 - 接收箱子 -----> 
接收打包好的数据 - 从箱子里面获取礼物 -----> 
解析数据包 - 签收走人 -----> 
释放资源 
package Mysocketnet.MyUDP;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
public class ReceiveMessageDom {
    public static void main(String[] args) throws IOException {
        //创建DatagramSocket
        //注意:要传输端口号码,而且传输的端口号码,要与传输端一致,要不然接受不到数据
        DatagramSocket ds = new DatagramSocket(10086);
        //接收数据,创建DatagramPacket空的数组对象接受传来的数据
        byte[] bytes = new byte[1024];
        DatagramPacket dp = new DatagramPacket(bytes, bytes.length);
        ds.receive(dp);
        //把数据拿出来
        InetAddress address = dp.getAddress();
        byte[] data = dp.getData();
        int length = dp.getLength();
        int port = dp.getPort();
        System.out.println("是"+address+"该IP通过"+port+"端口号,发过来的"+new String(data,0,length));
        //关闭窗口
        ds.close();
    }
}
 
dp.receive:需要等到接收到数据过后才进行下面代码的实现
练习:
 
 发送:
package Mysocketnet.MyUDP.Exercise;
import javax.sound.sampled.Port;
import java.io.IOException;
import java.net.*;
import java.util.Scanner;
//创建一个聊天室
//输入是键盘输入,直到输入的是886的时候才停止。
public class Send {
    public static void main(String[] args) throws IOException {
        //创建DatagramSocket(快递公司)
        DatagramSocket ds = new DatagramSocket();
        //打包数据
        //首先通过键盘输入数据,在集训打包
        Scanner sc = new Scanner(System.in);
        InetAddress address = InetAddress.getByName("127.0.0.1");
        //端口号
        int port = 10086;
        while (true){
            //键盘录入数据,请将数据传输为byte[]类型
            System.out.println("请输入数据");
            String str = sc.nextLine();
            byte[] bytes = str.getBytes();
            DatagramPacket dp = new DatagramPacket(bytes, bytes.length, address, port);
            //发送
            ds.send(dp);
            System.out.println("发送成功");
            if (str.equals("886")){
                System.out.println("聊天结束");
                break;
            }
        }
        //关闭
        ds.close();
    }
}
 
接收:
package Mysocketnet.MyUDP.Exercise;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
//创建一个聊天室
//接收数据,一直接收数据,采用死循环
public class Receive {
    public static void main(String[] args) throws IOException {
        //创建DatagramSocket(接收数据的端口号)
        DatagramSocket ds = new DatagramSocket(10086);
        //一直接收数据
        //创建空包裹来接受数据
        byte[] bytes = new byte[1024];
        while (true){
            //创建DatagramPacket
            DatagramPacket dp = new DatagramPacket(bytes, 0, bytes.length);
            //接收数据
            ds.receive(dp);
            System.out.println(new String(dp.getData())+"-------"+dp.getAddress());
        }
    }
}
 
1.6.1.1 UDP的三种通信方式
- 单播: 
单个发送数据
以前的代码就是单播 - 组播: 
发送一小部分数据
组播地址: 224.0.0.0 ~ 239.255.255.255
其中224.0.0.0 ~ 224.0.0.255 为预留的组播地址 - 广播: 
全部数据发送
广播地址: 255.255.255.255 
组播与上方代码不相同的地方是:
//创建MulticastSocket对象
MulticastSocket ms = new MulticastSocket()
//接收的地址改为
InetAddress address = InetAddress.getByName("224.0.0.1");
 
1.6.2 TCP协议
- 传输控制协议TCP(Transmission Control Protocol)
 - TCP协议是面向连接的通信协议。
速度慢,没有大小限制,数据安全 
由于传输数据相对较慢,但是传输时不会丢失数据,主要应用于:文字聊天,发送邮件
TCP通信程序
- TCP通信协议是一种可靠的网络协议,它在通信的两端各建立一个Socket对象
 通信之前要保证连接已经建立- 通过Socket产生
 IO流来进行网络通信
客户端(Socket):
- 创建客户端的Socket对象(Socket)与指定服务端连接
Socket(string host, int port) - 获取输出流,写数据
Outputstream getOutputstream() - 释放资源
void close() 
package Mysocketnet.MyTCP;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
//用TCP来创建监听窗口(发送数据)
public class client {
    public static void main(String[] args) throws IOException {
        //创建Socket对象
        Socket socket = new Socket("127.0.0.1", 10086);
        //创建连接通道
        OutputStream os = socket.getOutputStream();
        os.write("男孩女孩".getBytes());
        //清理资源
        os.close();
        socket.close();
    }
}
 
服务端:
- . 创建服务器端的Socket对象(ServerSocket)
ServerSocket(int port) - 监听客户端连接,返回一个Socket对象
Socket accept()
3 . 获取输入流,读数据,并把数据显示在控制台
Inputstream getInputstream() - 释放资源
void close() 
package Mysocketnet.MyTCP;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
//利用TCP来创建服务器端口(接收数据)
public class service {
    public static void main(String[] args) throws IOException {
    //创建Socket对象
        ServerSocket ss = new ServerSocket(10086);
        //创建接收数据
        Socket accept = ss.accept();
        //连接通道获取其传输的值
//        InputStream is = accept.getInputStream();
        //因为在这里创建的是字节流是一个字节一个字节的读取就会导致乱码
        //所有通过这里的转换流转成字符流
        BufferedReader br = new BufferedReader(new InputStreamReader(accept.getInputStream()));
        int b;
        while ((b = br.read()) != -1){
            System.out.println((char) b);
        }
        //清理资源
        accept.close();
        ss.close();
    }
}
 
注意事项:
- 我们在利用
 客户端传输数据的时候必须要保证连接正常,要么就会报错- 我们在创建的服务端,在读取数据的时候,可以利用转换流将
 字节流转换为字符流,不仅提高了效率,还防止了乱码
1.6.2.1 TCP底层原理

三次握手:
确保链接

四次挥手:
确保连接断开,并且使得数据处理完全

 个人理解:(可能不恰当,适当理解)
相当于就是先跟服务器说我要执行某个任务在服务器上,然后服务器同意后给与消息返回,但是要等到服务器手上的事情做完才能够发送同意消息,等到客户端拿到消息的时候,以为不成功,骗他的,再次向服务器确认信息后才安心的去执行任务






















