Java网络编程

1、网络编程三要素

一、IP地址

  • 设备在网络中的地址,是惟一标识

二、端口

  • 应用程序在设备中的惟一标识

三、协议

  • 数据在网络中传输的规则,常见的协议有UDP协议和TCP协议

2、IP地址

一、含义

  • IP地址,全称为Internet Protocol Address,网络协议地址。是分配给上网设备的数字标签。
  • 常见的IP分类有ipv4和ipv6

二、实践--终端ping网址

  • 在终端输入 ping www.itheima.com的过程解析

三、分类

ipv4:32bit来表示java

  • 问题:ipv4能分配的地址数量最多为256的四次方个,约为42亿,数量逐渐不够使用

ipv6:128bit来表示编程

四、相关命令(Mac)

  • 查看本机的IP地址数组

    • ifconfig
    • ifconfig | grep net 用管道符号+grep命令来过滤一下,更方便查看
  • 检查网络是否连通(还能够肯定域名的IP地址)安全

    • ping IP地址

五、特殊IP

  • 127.0.0.1:回送地址,本地回环地址。能够表明本机的IP地址,通常用来测试使用

六、Java中的InetAddress类

6.一、含义服务器

  • 表示IP地址

6.二、经常使用方法网络

  • static InetAddress getByName("String host"):经过主机名获取InetAdress对象,host能够是主机名,也能够是IP地址
  • String getHostName():获取主机名
  • String getHostAddress():获取IP地址

6.三、关于Mac查看和修改主机名和计算机名socket

https://www.jianshu.com/p/dbf2fa105f26tcp

3、端口

一、含义

  • 应用程序在设备中的惟一表示

二、端口号

  • 用两个字节表示的整数来标识。范围0~25535
  • 0~1023之间的端口号经常使用于一些知名的网络服务或应用,咱们本身使用1024及以上

三、注意

  • 一个端口号只能被一个应用程序来使用

4、协议

一、UDP协议

  • UDP(User Datagram Protocol)用户数据报协议测试

  • 面向无链接:只管发送,没必要先创建链接,均可以发送成功。若是二者已经链接,就能成功接收;3d

  • 特色

    • 速度快
    • 大小限制:最大为64K
    • 数据不安全,易丢失
  • 常见场景:音视频、普通数据

二、TCP协议

  • TCP(Transmission Control Protocol)传输控制协议
  • 面向链接:先保证链接已经创建,才传输数据
  • 特色
    • 速度慢
    • 没有大小限制
    • 数据安全
  • 经常使用场景:聊天

5、UDP通讯程序

一、发送端

  • 过程图示

  • 代码实现
public class ClientDemo {
    public static void main(String[] args) throws IOException {
        //1.找码头
        DatagramSocket ds = new DatagramSocket();

        //2.打包数据
        String message = "你好哇,李婷婷!";
        byte[] bytes = message.getBytes();
        InetAddress address = InetAddress.getByName("127.0.0.1");
        int port = 10000;
        DatagramPacket dp = new DatagramPacket(bytes, bytes.length, address, port);

        //3.发送数据
        ds.send(dp);

        //4.释放资源
        ds.close();
    }
}

二、接收端

  • 过程图示

  • 代码实现
public class ServerDemo {
    public static void main(String[] args) throws IOException {
        //1.找码头    ---表示从10000端口号接收数据,不然就是从随机端口接收数据
        DatagramSocket ds = new DatagramSocket(10000);

        //2.建立包
        byte[] bytes = new byte[1024];
        DatagramPacket dp = new DatagramPacket(bytes, bytes.length);

        //3.接受包
        ds.receive(dp);

        //4.打开包获得数据
        byte[] data = dp.getData();
        System.out.println(new String(data));

        //5.释放资源
        ds.close();
    }
}

三、实现通讯

  • 先运行接收端,保证创建了链接。
  • 再运行发送端,发送数据
  • 检查服务端,确实收到了数据

四、注意

  1. 若是接收端没有收到数据,就会死等(阻塞)。能够在接收先后加上输出语句来验证
  2. 新数组接收到的数据中,若是不能填满,会包含空格,可使用getLength()来获取数据的长度

其实,数组data是多余的,直接用bytes也能够获得数据

五、UDP三种通讯方式

5.一、单播:

  • 一对一发送
  • 以前写的代码就是单播通讯

5.二、组播

  • 一对多发送,可是多个接收端要是一组的

  • 代码实现

组播地址:244.0.0.0 ~ 244.255.255.255 。其中244.0.0.0 ~ 244.0.0.255是预留的组播地址

 

5.三、广播

  • 一对全部发送

  • 代码实现

6、TCP通讯程序

一、TCP通讯原理

  • TCP通讯协议是一种可靠的网络协议,因此在通讯两端各创建一个Socket对象

  • 通讯以前,要保证创建链接

  • 经过socket产生IO流来进行通讯

二、TCP发送数据的步骤

①、建立客户端Socket对象,与指定的服务端链接

②、获取输出流,写出数据

③、释放资源

  • 代码实现以下
public class ClientDemo {
    public static void main(String[] args) throws IOException {

        Socket socket = new Socket("127.0.0.1", 10000);

        OutputStream os = socket.getOutputStream();
        os.write("xian".getBytes());

        os.close();
        socket.close();
    }
}

//注意:此时若是咱们运行,是会报异常ConnectException,由于没法和接收端创建链接

三、TCP接受数据

①、建立服务端Socket对象(ServerSocket)

②、监听客户端,返回一个Socket对象

③、获取输入流,读数据,把数据显示在控制台

④、释放资源

  • 代码实现
public class ServerDemo {
    public static void main(String[] args) throws IOException {

        ServerSocket ss = new ServerSocket(10000);

        System.out.println(111);
        Socket accept = ss.accept();//等待客户端来进行链接,一直等待
        System.out.println(222);

        //复习
        InputStream is = accept.getInputStream();
        int b;
        while ((b = is.read() )!= -1){
            System.out.println((char) b);
        }
        
        is.close();
        ss.close();
    }
}

四、原理分析

  • 须要先运行服务端,服务端会执行到 ss.accept()处等待客户端链接
  • 客户端链接,发送数据
  • 服务端接受收据

注意

  • accept()方法是阻塞的,做用:等待客户端链接
  • 客户端链接服务器经过:三次握手

下面的类比就尼玛离谱,公平打在有才上

  • 针对客户端,往外写,用输出流;针对服务端,往里读,用输入流
  • read()方法是阻塞的
  • os.close()会附带一个结束标记,来让read结束
  • socket.close()关闭链接经过:四次挥手

五、练习一

客户端:发送数据,接受服务端反馈

服务端:接收数据,给出反馈

客户端代码

public class ClientDemo {
    public static void main(String[] args) throws IOException {
        //建立socket对象
        Socket socket = new Socket("127.0.0.1", 10086);

        //获取输出流,写出数据
        OutputStream os = socket.getOutputStream();
        os.write("hello".getBytes());
        socket.shutdownOutput();//关闭输出流,写一个结束标记给接收端,不会关闭socket

        //获取输入流,读入数据
        /*
        InputStream is = socket.getInputStream();
        int b;
        while ((b = is.read()) != -1){
            System.out.println((char) b);
        }
        */
        //由于接受的是中文,用字节流会乱码,socket又没有字符流,--->用缓冲流
        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String line;
        while ((line = br.readLine()) != null){
            System.out.println(line);
        }

        //关闭资源
        br.close();
        os.close();
        socket.close();

    }
}

服务端代码

public class ServerDemo {
    public static void main(String[] args) throws IOException {
        //建立socket对象
        ServerSocket ss = new ServerSocket(10086);

        //监听客户端,返回一个Socket对象
        Socket accept = ss.accept();

        //获取输入流,读入数据
        InputStream is = accept.getInputStream();
        int b;
        while ((b = is.read()) != -1){
            System.out.println((char) b);
        }

        //获取输出流,写出数据
        /*OutputStream os = accept.getOutputStream();
        os.write("你谁啊".getBytes());*/
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(accept.getOutputStream()));
        bw.write("你谁啊?");

        //关闭资源
        bw.close();
        is.close();
        ss.close();
    }
}

六、练习二

客户端:将文件上传到服务器,接受服务器的反馈

服务器:接受客户端上传的文件,上传完毕后给出反馈

客户端代码

public class ClientDemo {
    public static void main(String[] args) throws IOException {
        //建立socket
        Socket socket = new Socket("127.0.0.1", 10086);

        //本地流,读取本地文件
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("heima/ClientDir/java图标.jpg"));

        //网络中的流,写到服务器
        OutputStream os = socket.getOutputStream();
        BufferedOutputStream bos = new BufferedOutputStream(os);

        int b;
        while ((b = bis.read()) != -1){
            bos.write(b);
        }

        socket.shutdownOutput();//给服务器一个结束标记,表名传输完毕

        //获取服务端数据
        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String line;
        while ((line = br.readLine()) != null){
            System.out.println(line);
        }

        //关闭资源
        socket.close();
        bis.close();
    }
}

服务端代码

public class ServerDemo {
    public static void main(String[] args) throws IOException {

        //建立socket
        ServerSocket ss = new ServerSocket(10086);
        //等待链接
        Socket accept = ss.accept();

        //网络中的流,读取客户端数据
        BufferedInputStream bis = new BufferedInputStream(accept.getInputStream());
        //本地的流,持久化
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("heima/ServerDir/copy.jpg"));
        //读取,持久化到本地
        int b;
        while ((b = bis.read()) != -1){
            bos.write(b);
        }

        //发送反馈信息
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(accept.getOutputStream()));
        bw.write("上传成功");
        bw.newLine();
        bw.flush();

        //关闭资源
        ss.close();
        accept.close();//网络中的流,随着socket的关闭也会关闭
        bos.close();
    }
}
相关文章
相关标签/搜索