JavaSE 笔记【十三】网络编程

视频链接:Java零基础教程

网络编程

目的:直接或间接地通过网络协议与其他计算机实现数据交换,进行通讯

两个主要问题

  • 如何准确地定位网络上一台或多台主机;定位主机上的特定的应用
  • 找到主机后如何可靠高效的进行数据传输

通讯双方地址

  • IP
  • 端口号

一定的规则(即:网络通讯协议。有两套参考模型)

  • OSI参考模型:模型过于理想化,未能在因特网上进行广泛推广
  • TCP/IP参考模型(或TCP/IP协议):事实上的国际标准

网络通信协议:

OSI参考模型TCP/IP参考模型TCP/IP参考模型各层对应协议
应用层应用层HTTP、FTP、Telnet、DNS…
表示层应用层-
会话层应用层-
传输层传输层TCP、UDP…
网络层网络层IP、ICMP、ARP…
数据链路层物理层 + 数据链路层Link
物理层物理层 + 数据链路层-

通讯要素

IP地址

在Java中使用InetAddress类代表IP

分类:

  • IPv4:4个字节组成,4个0-255。大概434亿,30亿都在北美,亚洲4亿。2011年初已经用尽。以点分十进制表示,如192.168.0.1
  • IPv6:128位(16个字节),写成8位无符号整数,每个整数用四个十六进制位表示,数之间用冒号(: 分开),如:3ffe:3201:1401:1280:c8ff:fe4d:db39:1984

IP地址分类方式2: 公网地址(万维网使用)私有地址(局域网使用)。192.168.开头的就是私有地址,范围即为192.168.0.0 - 192.168.255.255,专门为组织机构内部使用

特点:不易记忆

InetAddress inet1 = InetAdderss.getByName("192.168.10.14");
InetAddress inet2 = InetAdderss.getByName("www.antherd.com");
InetAddress inet3 = InetAddress.getLocalhost();

inet1.getHostName(); // 获取域名
inet1.getHostAddress(); // 获取ip地址

本地回路地址:127.0.0.1,对应着:localhost

端口号

端口号标识正在计算机上运行的进程(程序)

  • 不同的进程有不同的端口号
  • 被规定为一个16位的整数 0~65535
  • 端口分类:
    公认端口:0~1023。被预先定义的服务器通信占用(如:HTTP占用端口80,FTP占用端口21,Telnet占用端口23)
    注册端口:1024~49151。分配给用户进程或应用程序。(如:tomcat占用端口8080,MySQL占用端口3306,Oracle占用端口1521等)
    动态/私有端口:49152~65535

端口号与IP地址的组合得出一个网络套接字:Socket

网络协议

计算机网络中实现通信必须有一些约定,即通讯协议,对速率、传输代码、代码结构、传输控制、出错控制等制定标准

问题:网络协议太复杂

计算机网络通讯涉及内容很多,比如指定源地址和目标地址,加密解密,压缩解压缩,差错控制,流量控制,路由控制,如何实现如此复杂的网络协议呢?

通讯协议分层的思想

在制定协议时,把复杂成分分解成一些简单的成分,再将它们复合起来。最常用的复合方式是层次方式,即同层间可以通信、上一层可以调用下一层,而与下一层不发生关系。各层互不影响,利于系统的开发和拓展。

传输层协议中有两个非常重要的协议:

  • 传输控制协议TCP(Transmission Control Protocol)
  • 用户数据包协议UDP(User Datagram Protocol)

TCP/IP 及其两个重要协议:传输控制协议(TCP)和网络互联协议(IP)而得名,实际上是一组协议,包括多个具有不同功能且互为关联的协议。

IP(Internet Protocol)协议是网络层的主要协议,支持网间互联的数据通信。
TCP/IP 协议模型从更实用的角度出发,形成了高效的四层体系结构,即物理链路层、IP层、传输层和应用层

TCP和UDP

TCP

  • 使用TCP协议前,需先建立TCP连接,形成传输数据通道
  • 传输前,采用“三次握手”方式,点对点通信,是可靠的
  • TCP协议进行通信的两个应用进程:客户端、服务端
  • 在连接中可进行大数据量的传输
  • 传输完毕,需释放已建立的连接,效率低

TCP三次握手
客户端或服务端均可主动发起挥手动作,在socket编程中,任何一方执行close() 操作即可产生挥手操作。
TCP四次挥手

UDP协议

  • 将数据、源、目的封装成数据包,不需要建立连接
  • 每个数据报的大小限制在64k
  • 发送不管对方是否准备好,接收方收到也不确认,故是不可靠的
  • 可以广播发送
  • 发送数据结束时无需释放资源,开销小,速度快
TCP网络编程案例
// 客户端
@Test
public void client() {
    Socket socket = null;
    OutputStream os = null;
    try {
        // 1. 创建Socket,指明服务器端的ip和端口号
        InetAddress inet = InetAddress.getByName("127.0.0.1");
        socket = new Socket(inet, 8899);
        // 2. 获取一个输出流,用于输出数据
        os = socket.getOutputStream();
        // 3. 写出数据的操作
        os.write("你好,我是客户端mm".getBytes());
        socket.shutdownOutput(); // 关闭数据的输出
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        // 4. 资源的关闭
        try {
            if (os != null) {
                os.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            if (socket != null) {
                socket.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

// 服务端
@Test
public void server() {
    Socket socket = null;
    InputStream is = null;
    try {
        // 1. 创建服务器的ServerSocket,指明自己的端口号
        ServerSocket ss = new ServerSocket(8899);
        // 2. 调用accept() 表示接受来自客户端的socket
        socket = ss.accept();
        // 3. 获取输入流
        is = socket.getInputStream();
        // 4. 读取输入流中的数据
        byte[] buffer = new byte[1024]; // 可能产生乱码
        int len;
        while((len = is.read(buffer)) != -1) {
            String str = new String(buffer, 0, len);
            System.out.print(str);
        }
        System.out.println("收到来自于:" + socket.getInetAddress().getHostAddress());
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        // 5. 关闭资源
        if (is != null) {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (socket != null) {
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

先启动服务端,然后启动客户端。

UDP网络编程案例
// 发送端
@Test
public void send() throws IOException {
    DatagramSocket socket = new DatagramSocket();

    String str = "我是UDP方式发送的消息";
    byte[] data = str.getBytes();
    InetAddress inet = InetAddress.getLocalHost();
    DatagramPacket packet = new DatagramPacket(data, 0, data.length, inet, 9000);
    socket.send(packet);
    socket.close();
}

// 接收端
@Test
public void receiver() throws IOException {
    DatagramSocket socket = new DatagramSocket(9000);
    byte[] buffer = new byte[100];
    DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);
    socket.receive(packet);

    System.out.println(new String(packet.getData(), 0, packet.getLength()));

    socket.close();
}
URL编程
  • URL(Uniform Resource Locator):统一资源定位符,它表示Internet上某一资源的地址
  • 它是一种具体的URI,即URL可以用来表示一个资源,而且还指明了如何locate这个资源
  • 通过URL,我们可以访问Internet上的各种网络资源,比如最常见的www,ftp站点。浏览器通过解析给定的URL可以在网络上查找响应的文件或其他资源
  • URL的基本结构由5部分组成:
    <传输协议>://<主机名>:<端口号>/<文件名>#片段名?参数列表
    例如:http://192.168.1.100:8080/helloworld/index.jsp#a?username=shkstart&password=123
    #片段名:即锚点,例如看小说,直接定位到章节
    参数列表格式:参数名=参数值&参数名=参数值…
HttpURLConnection urlConnection = null;
InputStream is = null;
FileOutputStream fos = null;
try {
    URL url = new URL("http://localhost:8080/examples/beauty.jpg?username=Tom");
    System.out.println(url.getProtocol());
    System.out.println(url.getHost());
    System.out.println(url.getPort());
    System.out.println(url.getPath());
    System.out.println(url.getFile());
    System.out.println(url.getQuery());

    // 下载资源
    urlConnection = (HttpURLConnection) url.openConnection();
    is = urlConnection.getInputStream();
    fos = new FileOutputStream(new File("beauty2.jpg"));
    byte[] buffer = new byte[1024];
    int len;
    while ((len = is.read(buffer)) != -1) {
        fos.write(buffer, 0, len);
    }
} catch (IOException e) {
    e.printStackTrace();
} finally {
    // 关闭资源
    if (is != null) {
        try {
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    if (fos != null) {
        try {
            fos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    if (urlConnection != null) {
        urlConnection.disconnect();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值