【Java学习笔记】——网络编程

【笔记】跟着狂神学Java网络编程

前期了解

  • 网络传输的要素

    1. 通信双方:IP、端口号
    2. 通信协议:
      七层模型和五层模型
  • TCP/UDP传输(我的理解)

    1. TCP面向连接,安全性高,出错重传。(用户传输协议)
      三次握手,四次挥手
      客户端/服务端 (C/S模式)
      传输完毕,释放连接,效率低
    2. UDP面向无连接,安全性较差,出错不重传。(用户数据报传输协议)
      收发双方的身份不固定,既可以是客户端,也可以是服务端

IP地址

  • InetAddress类
    (包:java.net.InetAddress)
  • 分类:
    1. IPV4、IPV6
    2. A~E
    3. 公网(互联网)、私网(局域网)
    4. 域名:DNS域名解析、一个域名对应一个IP地址,一个IP地址可以有多个域名
  • 创建IP地址对象及常用方法
//getByName(String host)
InetAddress address = InetAddress.getByName("127.0.0.1");
InetAddress address1 = InetAddress.getByName("localhost");
InetAddress address2 = InetAddress.getByName("www.baidu.com");

//常用方法
//返回此 InetAddress 对象的原始 IP 地址。
System.out.println(address2.getAddress());

//返回 IP 地址字符串(以文本表现形式)。
System.out.println(address2.getHostAddress());

// 获取此 IP 地址的主机名。
System.out.println(address2.getHostName());

//获取此 IP 地址的完全限定域名。
System.out.println(address2.getCanonicalHostName());

//返回此 IP 地址的哈希码。
System.out.println(address2.hashCode());


端口

端口表示计算机上的一个程序的进程

  • 不同的进程有不同的端口好,用来区分软件

  • 规定范围 0~65535

  • TCP:80端口和 UDP:80端口不冲突,同一个协议下的端口号不能冲突。

  • 分类:

    1. 公有端口:0~1023
      • HTTP: 80
      • HTTPS :443
      • FTP:21
      • Telnet:23
    2. 程序注册端口:1024~49151,分配用户或程序
      • Tomcat:8080
      • MySQL:3306
      • Oracle:1521
    3. 动态、私有: 49152~65535
  • 控制台查询

netstat -ano #查看所有的端口
netstat -ano|findstr "5900" #查看指定的端口
tasklist|findstr "2440" #查看指定端口的进程(我电脑上的QQ)

  • 创建端口对象及常用方法
//InetSocketAddress(String hostname, int port)
InetSocketAddress address = new InetSocketAddress("127.0.0.1",8888);

//常用方法
address.HostName();
address.getPort();
address.getAddress();
address.hashCode();

TCP 实现消息传输

要点:

  • 客户端
    Socket:套接字是两台机器间通信的端点,实现客户端套接字。
  • 服务端
    ServerSocket:实现服务端套接字,服务器套接字等待请求通过网络传入。
  • 熟练掌握 I/O

Client(客户端)

package TcpTest;

import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;

public class Client {
    public static void main(String[] args) {

        //创建客户端套接字
        Socket socket = null;
        //输出流
        OutputStream os = null;
        
        try {
            //服务器端口及本地ip
            InetAddress localHost = InetAddress.getByName("127.0.0.1");
            int port = 9999;

            //客户端创建一个Socket连接
            socket = new Socket(localHost, port);

            //发送消息
            os = socket.getOutputStream();
            os.write("Hello".getBytes());
            
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //关闭流
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

Server (服务端)

package TcpTest;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
    public static void main(String[] args) {
        //创建服务器套接字
        ServerSocket serverSocket = null;
        //实例化一个Socket类型的变量
        Socket socket = null;
        //输入流
        InputStream inputStream = null;
        //字节流
        ByteArrayOutputStream baos = null;

        try {
            //创建一个端口
            serverSocket = new ServerSocket(9999);

            //阻塞等待客户端连接,accept()返回一个Socket类型的变量
            socket = serverSocket.accept();

            //读取客户端(socket中的I/O流)消息
            inputStream = socket.getInputStream();

            //管道流存储消息并打印
            baos = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len;
            while ((len = inputStream.read(buffer)) != -1) {
                baos.write(buffer, 0, len);
            }

            //打印
            System.out.println(baos.toString());

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //关闭流
            if (baos != null) {
                try {
                    baos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }


            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (serverSocket != null) {
                try {
                    serverSocket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}


UDP实现消息传输

要点:

  • 1.UDP 发送数据用DatagramSocket类 用send 方法
  • 2.读取输入流用BufferedReader类 读取输入流InputStreamReader
  • 3.创建包用DatagramPacket类,熟悉一下几个他的构造器

Send

package UdpChat;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

/*
* 1.UDP 发送数据用DatagramSocket类 用send 方法
* 2.读取输入流用BufferedReader类 读取输入流InputStreamReader
* 3.创建包用DatagramPacket类,熟悉一下几个他的构造器
* */


public class Send {
    public  static void main(String[] args) throws Exception {
        //建立接收端口
        DatagramSocket socket = new DatagramSocket(8888);
        
        //要发送的包,从控制台读取数据
        InetAddress address = InetAddress.getByName("127.0.0.1");
        int port = 6666;
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

        while (true) {
            String data = reader.readLine();
            byte[] datum = data.getBytes();
            //par: 1.发送的数据 2.起始位置 3.长度 4.目的地地址 5.目的地端口号
            DatagramPacket packet = new DatagramPacket(datum,0,datum.length,address,port);

            //发送数据包
            socket.send(packet);

            //判断结束
            if (data.trim().equals("bye")) {
                System.out.println("---End Conversation---");
                break;
            }
        }
        //关闭socket
        socket.close();
    }
}

Receive

package UdpChat;

import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class Receive {
    public static void main(String[] args) throws Exception {
        //建立接收端口
        DatagramSocket socket = new DatagramSocket(6666);
        
        while (true) {
            //数据包
            byte[] container = new byte[1024];
            DatagramPacket packet = new DatagramPacket(container, 0, container.length);

            //阻塞式接收包裹
            socket.receive(packet);

            //判断断开,获取包数据转成字符串再判断
            byte[] data = packet.getData();
            String receiveData = new String(data, 0, data.length);
            System.out.println(receiveData);

            //trim()去掉字符串头尾的空白字符
            if (receiveData.trim().equals("bye")) {
                System.out.println("---End Conversation---");
                break;
            }
        }

        //关闭socket
        socket.close();
    }
}


UDP 多线程实现在线咨询(本地)

Send

package UdpConsult;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.*;

public class Send implements Runnable {


    DatagramSocket socket = null;
    BufferedReader reader = null;
    //目的地地址和端口
    private InetAddress desAddress;
    private int desPort;
    //本地端口
    private int fromPort;

    //1.本地端口 2.目的地地址 3.目的地端口
    public Send( int fromPort, InetAddress desAddress, int desPort) {
        this.desAddress = desAddress;
        this.desPort = desPort;
        this.fromPort = fromPort;
        try {
            socket = new DatagramSocket(this.fromPort);
            reader = new BufferedReader(new InputStreamReader(System.in));
        } catch (SocketException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        while (true) {
            try {
                //创建数据包
                String data = reader.readLine();
                byte[] datum = data.getBytes();
                DatagramPacket packet = new DatagramPacket(datum,0,datum.length,this.desAddress,this.desPort);
                //发送数据包
                socket.send(packet);

                //判断断开连接
                if (data.trim().equals("bye")) {
                    System.out.println("---End Consult---");
                    break;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        //关闭socket
        try {
            reader.close();
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

Receive

package UdpConsult;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

public class Receive implements Runnable {
    //创建本地信息
    DatagramSocket socket = null;
    //本地接收端口
    private int port;
    //发送方身份
    private String fromName;


    public Receive(int port, String fromName) {
        this.fromName = fromName;
        this.port = port;
        //创建本地接收端口号
        try {
            socket = new DatagramSocket(this.port);
        } catch (SocketException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        while (true) {
            try {
                //创建数据包
                byte[] container =new byte[1024];
                DatagramPacket packet = new DatagramPacket(container,0,container.length);

                //接收数据
                socket.receive(packet);
                //转换数据格式
                byte[] data = packet.getData();
                String datum = new String(data,0,data.length);
                System.out.println(fromName + ":" + datum);

                //判断断开连接
                if (datum.trim().equals("bye")) {
                    System.out.println("---End Consult---");
                    break;
                }

            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        //关闭socket
        socket.close();
    }
}

实现咨询

Student 和 Teacher 相互通信
Student:

package UdpConsult;

import java.net.InetAddress;

/*
* 存在的问题:
* 在发出bye之后不能断开连接
* */

public class Student {
    public static void main(String[] args) throws Exception {
        //从8888端口发出,到接收端的6666端口接收
        new Thread(new Send(8888, InetAddress.getByName("127.0.0.1"),6666)).start();
        new Thread(new Receive(9999, "老师")).start();
    }
}

Teacher:

package UdpConsult;

import java.net.InetAddress;

public class Teacher {
    public static void main(String[] args) throws Exception {
        //从7777端口发出去,到9999端口接收
        new Thread(new Send(7777, InetAddress.getByName("127.0.0.1"), 9999)).start();
        new Thread(new Receive(6666, "学生")).start();
    }
}


URL 下载网络资源

  • 了解其他几个URL类的构造器。
  • 了解HttpURLConnection类。
  • 创建链接用URL类创建的变量去调用openConnection() 方法。
  • 熟练使用I/O
package UrlTest;

import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;

public class UrlGet {
    public static void main(String[] args) throws Exception {
        //要下载的内容的URL
        URL url = new URL("https://i0.hdslb.com/bfs/archive/86848c76a76fe46d84d6ef1ab735d9398ed3ee8e.png");

        //创建连接
        HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();

        //获取连接中的输入流
        InputStream inputStream = urlConnection.getInputStream();

        //文件输出流,参数:保存到本地的文件名
        FileOutputStream fos = new FileOutputStream("bilibili.png");

        byte[] buffer = new byte[1024];
        int len;
        while ((len=inputStream.read(buffer)) != -1) {
            //写出数据
            fos.write(buffer,0,len);
        }

        fos.close();
        inputStream.close();
        urlConnection.disconnect();
    }
}

以上都是我跟着狂神学Java多线程时的一些代码和感悟,纯属当作笔记来分享,如果大家发现了我笔记中的错误,可以多多指正,我会认真修改,虚心求教的!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值