Java基础进阶_day17_(网络编程)

Java基础进阶_day17_(网络编程)

1. 网络编程

1.1 网络编程三要素

网络编程三要素:
    A:IP地址
    B:端口
    C:协议
IP地址:
    网络中计算机的唯一标识。
    计算机只能识别二进制的数据,所以我们的IP地址应该是一个二进制的数据。
    但是呢,我们配置的IP地址确不是二进制的,为什么呢?
        IP:192.168.1.100
        换算:11000000 10101000 00000001 01100100
    假如真是:11000000 10101000 00000001 01100100的话。
    我们如果每次再上课的时候要配置该IP地址,记忆起来就比较的麻烦。
    所以,为了方便表示IP地址,我们就把IP地址的每一个字节上的数据换算成十进制,然后用.分开来表示:
        "点分十进制"
    IP地址的组成:网络号段+主机号段
        A类:第一号段为网络号段+后三段的主机号段
            一个网络号:256*256*256 = 16777216
        B类:前二号段为网络号段+后二段的主机号段
            一个网络号:256*256 = 65536
        C类:前三号段为网络号段+后一段的主机号段
            一个网络号:256
    IP地址的分类:
        A类  1.0.0.1---127.255.255.254   (1)10.X.X.X是私有地址(私有地址就是在互联网上不使用,而被用在局域网络中的地址)                           (2)127.X.X.X是保留地址,用做循环测试用的。
        B类  128.0.0.1---191.255.255.254 172.16.0.0---172.31.255.255是私有地址。169.254.X.X是保留地址。
        C类  192.0.0.1---223.255.255.254 192.168.X.X是私有地址
        D类  224.0.0.1---239.255.255.254     
        E类  240.0.0.1---247.255.255.254
    两个DOS命令:
        ipconfig 查看本机ip地址
        ping 后面跟ip地址。测试本机与指定的ip地址间的通信是否有问题
    特殊的IP地址:
        127.0.0.1 回环地址(表示本机)
        x.x.x.255 广播地址
        x.x.x.0 网络地址
端口号:
    正在运行的程序的标识。
    有效端口:0~65535,其中0~1024系统使用或保留端口。
协议:
    通信的规则
    UDP:
        把数据打包
        数据有限制
        不建立连接
        速度快
        不可靠
    TCP:
        建立连接通道
        数据无限制
        速度慢
        可靠
    举例:
        UDP:发短信
        TCP:打电话

1.2 UDP通信编程

 * UDP通信:
 *      将数据源和目的封装成数据包中,不需要建立连接;
 *      每个数据报的大小在限制在64k;
 *      因无连接,是不可靠协议;
 *      不需要建立连接,速度快.
 * Socket套接字:
 *      网络上具有唯一标识的IP地址和端口号组合在一起才能构成唯一能识别的标识符套接字.
 * Socket原理机制:
 *      通信的两端都有Socket;
 *      网络通信其实就是Socket间的通信;
 *      数据在两个Socket间通过IO传输.
 * UDP通信的步骤:
 *      A:创建DatagramSocket与DatagramPacket类
 *      B:建立发送端,接收端;
 *      C:建立数据包;
 *      D:调用Socket的发送接收方法;
 *      E:关闭Socket;
 *      F:发送端与接收端是两个独立的运行程序.
 * DatagramSocket类:此类表示用来发送和接收数据报包的套接字.

案例代码

/*
 * 使用线程,不断发送数据
 */
public class SendData {
    public static void main(String[] args) throws IOException,
            UnknownHostException {
        // 创建发送端对象,绑定到本地的12310端口,不指定端口时,默认使用的本机上可用的端口号
        final DatagramSocket ds = new DatagramSocket(12311);
        // 创建发送数据包
        byte[] bys = new byte[1024];
        // 设定发送到对方的数据,长度,地址,IP地址,端口
        final DatagramPacket dp = new DatagramPacket(bys, bys.length,
                InetAddress.getLocalHost(), 12309);
        new Thread() {
            @Override
            public void run() {
                // 设置数据并发送
                Scanner sc = new Scanner(System.in);
                while(true) {
                    String line = sc.nextLine();
                    if(line.equals("somnus")) {
                        break;
                    }
                    dp.setData(line.getBytes());
                    try {
                        ds.send(dp);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }finally {
                        // 释放资源
                        // ds.close();
                    }
                }
            }
        }.start();
    }
}

/*
 * 使用线程,不断接收数据
 */
public class ReceiveData {
    public static void main(String[] args) throws IOException {
        // 创建接收端套接字,绑定到本地的12309端口上
        final DatagramSocket ds = new DatagramSocket(12309);
        // 创建接收数据的套接字
        byte[] bys = new byte[1024];
        final DatagramPacket dp = new DatagramPacket(bys, bys.length);
        // 接收数据并输出
        new Thread() {
            @Override
            public void run() {
                try {
                    while(true) {
                        ds.receive(dp);
                        System.out.println(dp.getAddress().getHostAddress()+":"+new String(dp.getData(), 0, dp.getLength()));
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }finally {
                    // 释放资源
                     ds.close();
                }
            }
        }.start();

    }
}

1.3 TCP通信编程

 * TCP通信:
 *      建立连接,形成传输数据的通道;
 *      在连接中进行大数据量传输;
 *      通过三次握手完成连接,是可靠协议;
 *      必须建立连接,效率会稍低.
 * TCP通信步骤:
 *      A:创建Socket客户端和ServerSocket服务端对象;
 *      B:建立客户端和服务器端;
 *      C:建立连接后,通过Socket中的IO流进行数据的传输;
 *      D:关闭socket;
 *      E:同样,客户端与服务器端是两个独立的应用程序.

案例代码

/*
 * 将文件上传到服务器,客户端
 */
public class UpCilent {
    public static void main(String[] args) throws IOException {
        // 获取文件路径
        File file = getFile();
        // 将文件名上传到服务器进行校验是否存在
        Socket client = new Socket("127.0.0.1", 12306);
        // 创建输出流对象
        BufferedOutputStream bos = new BufferedOutputStream(client.getOutputStream());
        // 向服务器发送文件名
        String fileName = file.getName();
        bos.write(fileName.getBytes());
        // 将缓冲区的数据刷出
        bos.flush();
        // 创建输入流对象
        BufferedInputStream bis = new BufferedInputStream(client.getInputStream());
        // 获取服务器对文件名校验的结果
        byte[] bys = new  byte[1024];
        int len = bis.read(bys);
        String result = new String(bys, 0, len);
        if("存在".equals(result)) {
            System.out.println("您要上传的文件已经存在,不能重复上传!");
            client.close();
            return;
        }
        // 文件不存在,则上传
        BufferedInputStream bis2 = new BufferedInputStream(new FileInputStream(file));
        while((len = bis2.read(bys)) != -1) {
            bos.write(bys, 0, len);
            bos.flush();
        }
        // 释放资源
        bis2.close();
        client.close();
    }
    public static File getFile() {
        // 定义键盘录入对象
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入一个文件的路径名:");
        while(true) {
            File file = new File(sc.nextLine());
            if(!file.exists()) {
                System.out.println("您输入的文件路径不存在,请重新输入:");
            } else if(file.isDirectory()) {
                System.out.println("您输入的是文件夹路径,请输入文件路径:");
            } else {
                return file;
            }
        }
    }
}

/*
 * 上传文件到服务器,服务器端
 */
public class FileServer {
    public static void main(String[] args) throws IOException {
        // 创建服务器socket对象
        ServerSocket server = new ServerSocket(12306);
        // 创建存储接收客户端文件的文件夹
        final File update = new File("update");
        if(! update.exists()) {
            update.mkdir();
        }
        // 持续接收客户端连接
        while(true) {
            final Socket s = server.accept();
            // 创建线程接收客户端连接
            new Thread() {
                public void run() {
                    try {
                        BufferedInputStream bis = new BufferedInputStream(s.getInputStream());
                        BufferedOutputStream bos = new BufferedOutputStream(s.getOutputStream());
                        byte[] bys = new byte[1024];
                        int len = bis.read(bys);
                        String fileName = new String(bys, 0, len);
                        File file = new File(update, fileName);
                        if(file.exists()) {
                            bos.write("存在".getBytes());
                            bos.flush();
                            // 文件存在,结束程序
                            s.close();
                            return;
                        } else {
                            // 文件不存在则返回标识
                            bos.write("不存在".getBytes());
                            bos.flush();
                        }
                        // 如果文件不存在,则上传
                        BufferedOutputStream bos2 = new BufferedOutputStream(new FileOutputStream(file));
                        while((len = bis.read(bys)) != -1) {
                            bos2.write(bys, 0, len);
                            bos2.flush();
                        }
                        // 释放资源
                        bos2.close();
                        s.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }.start();
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章