Java无难事(笔记)-Lesson10-网络编程

该课内容: Java网络编程. 基于TCP的套接字编程. 基于UDP的套接字编程. URL和URI.一个实用的下载程序.


计算机网络.

计算机网络是相互连接的独立自主的计算机的集合. 最简单的网络形式由两台计算机组成.


IP地址.

  • IP网络中每台主机都必须有一个惟一的IP地址.
  • IP地址是一个逻辑地址.
  • 因特网上的IP地址具有全球唯一性.
  • 32位. 4个字节. 常用点分十进制的格式表示. 例如. 192.168.0.16

协议.

  • 为进行网络中的数据交换(通信)而建立的规则、标准或约定。(=语义+语法+规则)
  • 不同层具有各自不同的协议

ISO/OSI七层参考模型.

Java无难事(笔记)-Lesson10-网络编程

  • 通信实体的对等层之间不允许直接通信.
  • 各层之间是严格单向依赖.
  • 上层使用下层提供的服务— Service user.
  • 下层向上层提供服务 — Service provider.

OSI各层所使用的协议.

  • 应用层:远程登录协议Telnet. 文件传输协议FTP. 超文本传输协议HTTP. 域名服务DNS. 简单邮件传输协议SMTP. 邮局协议POP3等.
  • 传输层:传输控制协议TCP、用户数据报协议UDP。

    a) TCP:面向连接的可靠的传输协议。

    b) UDP:是无连接的,不可靠的传输协议。

  • 网络层:网际协议IP、Internet互联网控制报文协议ICMP、Internet组管理协议IGMP。

数据封装.

  • OSI参考模型中. 对等层协议之间交换的信息单元统称为协议数据单元(PDU,Protocol Data Unit).
  • OSI参考模型中每一层都要依靠下一层提供的服务.
  • 为了提供服务. 下层把上层的PDU作为本层的数据封装. 然后加入本层的头部(和尾部). 头部中含有完成数据传输所需的控制信息.
  • 这样. 数据自上而下递交的过程实际上就是不断封装的过程. 到达目的地后自下而上递交的过程就是不断拆封的过程. 由此可知. 在物理线路上传输的数据. 其外面实际上被包封了多层“信封”.
  • 但是. 某一层只能识别由对等层封装的“信封”. 而对于被封装在“信封”内部的数据仅仅是拆封后将其提交给上层. 本层不作任何处理.

TCP/IP模型.

TCP/IP包括: 应用层. 传输层. 网络层. 网络接口.


端口.

  • 端口是一种抽象的软件结构(包括一些数据结构和I/O缓冲区). 应用程序通过系统调用与某端口建立连接(binding)后. 传输层传给该端口的数据都被相应的进程所接收. 相应进程发给传输层的数据都通过该端口输出.
  • 端口用一个整数型标识符来表示. 即端口号. 端口号跟协议相关. TCP/IP传输层的两个协议TCP和UDP是完全独立的两个软件模块. 因此各自的端口号也相互独立. 端口通常称为协议端口(protocol port) . 简称端口.
  • 端口使用一个16位的数字来表示. 它的范围是0~65535. 1024以下的端口号保留给预定义的服务. 例如. http使用80端口.

基于TCPsocket编程.

Java无难事(笔记)-Lesson10-网络编程

  • 服务器程序编写:

   ①调用ServerSocket(int port)创建一个服务器端套接字,并绑定到指定端口上;②调用accept(),监听连接请求,如果客户端请求连接,则接受连接,返回通信套接字。③调用Socket类的getOutputStream()和getInputStream获取输出流和输入流,开始网络数据的发送和接收。④最后关闭通信套接字。

  • 客户端程序编写:

  ①调用Socket()创建一个流套接字,并连接到服务器端; ②调用Socket类的getOutputStream()和getInputStream获取输出流和输入流,开始网络数据的发送和接收。 ③最后关闭通信套接字。

EX. 基于TCP的Socket编程

Java无难事(笔记)-Lesson10-网络编程
package test;
import java.net.*;
import java.io.*;
public class Test extends Thread{
    private Socket s;
    public Test (Socket s){
        this.s = s;
    }
    public void run(){
        try{
            OutputStream os = s.getOutputStream();
            InputStream is = s.getInputStream();
            os.write("hello.".getBytes());
            byte[] buf = new byte[100];
            int len = is.read(buf);
            System.out.println(new String(buf, 0, len));
            os.close();
            is.close();
            s.close();
        }
        catch (Exception ex){
            ex.printStackTrace();
        }
    }
    public static void main(String[] args){
        if (args.length > 0)
            server();
        else
            client();
    }
    public static void server(){
        try{
            // 创建套接字.绑定到端口号为6000的端口上.
            ServerSocket ss = new ServerSocket(6000);
            // 一旦有请求就创建一个线程.进行处理
            while (true){
                Socket s = ss.accept();
                new Test(s).start();
            }            
            //ss.close();
        }
        catch(Exception ex){
            ex.printStackTrace();
        }
    }
    public static void client(){
        try{
            // 客户端的端口需要与服务器端口号相同.
            // 注意这里ip地址使用的是本机地址.
            Socket s = new Socket(InetAddress.getByName(null), 6000);
            OutputStream os = s.getOutputStream();
            InputStream is = s.getInputStream();
            os.write("hello too.".getBytes());
            byte[] buf = new byte[100];
            int len = is.read(buf);
            System.out.println(new String(buf, 0, len));
            os.close();
            is.close();
            s.close();
        }
        catch(Exception ex){
            ex.printStackTrace();
        }
        
    }
}
Java无难事(笔记)-Lesson10-网络编程

基于UDPsocket编程.

  • 接收端程序编写:

  ①调用DatagramSocket(int port)创建一个数据报套接字,并绑定到指定端口上;②调用DatagramPacket(byte[] buf, int length),建立一个字节数组以接收UDP包 。③调用DatagramSocket类的receive(),接收UDP包。④最后关闭数据报套接字。

  • 发送端程序编写:

  ①用DatagramSocket()创建一个数据报套接字; ②调用DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port),建立要发送的UDP包。 ③调用DatagramSocket类的send(),发送UDP包。④最后关闭数据报套接字。

EX. 基于UDP的Socket编程

Java无难事(笔记)-Lesson10-网络编程
package test;
import java.net.*;
import java.io.*;
public class Test extends Thread{
    public static void main(String[] args){
        
    }
    public static void recv(){
        try{
            DatagramSocket ds = new DatagramSocket(6000);
            byte[] buf = new byte[100];
            DatagramPacket dp = new DatagramPacket(buf, 100);
            ds.receive(dp);
            System.out.println(new String(buf, 0, dp.getLength()));
            
            String str = "hello too";
            DatagramPacket dpSend = new DatagramPacket(str.getBytes(), str.length(), dp.getAddress(), dp.getPort());
            ds.send(dpSend);
            ds.close();
            
        }
        catch (Exception ex){
            ex.printStackTrace();
        }
    }
    public static void send(){
        try{
            DatagramSocket ds = new DatagramSocket();
            String str = "Hello";
            DatagramPacket dp = new DatagramPacket(str.getBytes(), str.length(), InetAddress.getByName(null), 6000);
            ds.send(dp);
            
            byte[] buf = new byte[100];
            DatagramPacket dpRecv = new DatagramPacket(buf, 100);
            ds.receive(dpRecv);
            System.out.println(new String(buf, 0, dpRecv.getLength()));
            ds.close();            
        }
        catch (Exception ex){
            ex.printStackTrace();
        }
    }
}
Java无难事(笔记)-Lesson10-网络编程

URLURI.

  • URL(Uniform Resource Locator ),通用资源定位符。http://www.mybole.com.cn/index.asp就是一个URL。
  • URI(Uniform Resource Identifier),通用资源标识符。
  • URI纯粹是个符号结构,用于指定构成Web资源的字符串的各个不同部分。URL是一种特殊类型的URI,它包含了用于查找某个资源的足够信息。其它的URI,例如:mailto:myoble@mybole.com.cn则不属于定位符,因为它里面不存在根据该标识符来查找的任何数据。这种URI称为URN(通用资源名)。
  • 在Java库中,URI类不包含用于访问通用资源标识符设定的任何方法,它的唯一作用是进行分析。相反,URL类则可以打开到达资源的一个字符串。

EX. 文件下载例子.

Java无难事(笔记)-Lesson10-网络编程
package test;
import java.net.*;
import javax.swing.*;
import java.awt.event.*;
import java.io.*;
public class Test extends Thread{
    public static void main(String[] args){
        JFrame jf = new JFrame("download");
        jf.setSize(600, 400);
        jf.setLocation(100, 100);
        JPanel p = new JPanel();
        JLabel l = new JLabel("input URL:");
        final JTextField tf = new JTextField(30);
        p.add(l);
        p.add(tf);
        jf.getContentPane().add(p, "North");
        final JTextArea ta = new JTextArea();
        jf.getContentPane().add(ta, "Center");
        JButton btn = new JButton("download");
        btn.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e){
                String str = tf.getText();
                try{
                    URL url1 = new URL(str);
                    URLConnection urlconn = url1.openConnection();
                    String line = System.getProperty("line.separator");
                    ta.append("Host " + url1.getHost() + line);
                    ta.append("Port " + url1.getDefaultPort() + line);
                    ta.append("ContentType " + urlconn.getContentType() + line);
                    ta.append("ContextLength " + urlconn.getContentLength());
                    InputStream is = urlconn.getInputStream();
                    FileOutputStream fos = new FileOutputStream("1.html");
                    int data;
                    while ((data = is.read()) != -1){
                        fos.write(data);
                    }
                    fos.close();
                    is.close();
                }
                catch (Exception ex){
                    ex.printStackTrace();
                }
                
            }
        });
        jf.getContentPane().add(btn, "South");
        jf.addWindowListener(new WindowAdapter(){
            public void WindowClosing(WindowEvent e){
                System.exit(0);
            }
        });
        jf.show();
    }
}
Java无难事(笔记)-Lesson10-网络编程

Java无难事(笔记)-Lesson10-网络编程,布布扣,bubuko.com

Java无难事(笔记)-Lesson10-网络编程

上一篇:Kubernetes namespace删除失败


下一篇:C++模板实例化(1)