Java无难事10

1、计算机网络:
计算机网络是相互连接的独立自主的计算机的集合,最简单的网络形式由两台计算机组成;
一台主机和另一台主机通信,首先要知道想要通信的主机的名字(IP地址),两台主机要采用同样的协议,还要指定端口号;

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

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

4、网络异质性问题的解决:
网络体系结构就是使这些用不同媒介连接起来的不同设备和网络系统在不同的应用环境下实现互操作性,并满足各种业务需求的一种粘合剂,它营造了一种“生存空间”——任何厂商的任何产品、以及任何技术只要遵守这个空间的行为规则,就能够在其中生存并发展;
网络体系结构解决异质性问题采用的是分层方法——把复杂的网络互联问题划分为若干个较小的、单一的问题,在不同层上予以解决;(就像我们在编程时把问题分解为很小的模块来解决一样);

5、ISO/OSI七层参考模型:
OSI(Open System Interconnection)参考模型将网络的不同功能划分为七层;
从上往下分别为:
应用层——处理网络应用
表示层——数据表示
会话层——主机间通信
传输层——端到端的连接(为原端主机到目的端主机提供可靠的数据传输服务,隔离网络的上下层协议,使得网络应用与下层协议无关)
网络层——寻址和最短路径(找出最佳传输线路)
数据链路层——介质访问(接入)(加强物理层的传输功能,建立一条无差错的传输线路)
物理层——二进制传输(确定如何在通信信道上传输比特流)
通信实体的对等层之间不允许直接通信;
单层之间是严格单向依赖;
上层使用下层提供的服务—Service user;
下层向上层提供服务—Service provider;
在这里插入图片描述
对等通信实质:
对等层实体之间虚拟通信;
下层向上层提供服务,实际通信在最底层完成;

6、OSI各层所使用的协议:
应用层:远程登录协议Telnet、文件传输协议FTP、超文本传输协议HTTP、域名服务DNS、简单邮件传输协议SMTP、邮局协议POP3等;
传输层: 传输控制协议TCP、用户数据报协议UDP;
TCP:面向连接的可靠的传输协议(三次握手建立连接,数据确认,数据重传)
UDP:面向无连接的,不可靠的传输协议(不需要建立连接,实时性高)
网络层:网际协议IP、Internet互联网控制报文协议ICMP、Internet组管理协议IGMP;

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

8、TCP/IP模型:
TCP/IP起源于美国国防部高级研究规划署(DARPA)的一项研究计划——实现若干台主机的相互通信;
现在TCP/IP已成为Internet上通信的工业标准;
TCP/IP模型包括四个层次:
* 应用层
* 传输层
* 网络层
* 网络接口
在这里插入图片描述

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

10、套接字(Socket)的引入:
为了能够方便的开发网络应用软件,由美国伯克利大学在Unix上推出了一种应用程序访问通信协议的操作系统调用Socket(套接字)。Socket的出现,使程序员可以很方便地访问TCP/IP,从而开发各种网络应用的程序;
随着Unix的应用推广,套接字在编写网络软件中得到了极大的普及。后来,套接字又被引进了Windows等操作系统中。Java语言也引入了套接字编程模型。

11、基于TCP的Socket编程:
在网络中,等待连接请求到来的一方为服务器端(Sever);发起连接请求的一端为客户端(Client);
在Java中,用于编写网络程序的类是由java.net包提供的;java.net中Class ServerScoket用于创建服务器端的套接字,Class Socket用于创建客户端的套接字。
在这里插入图片描述

//Java中利用socket实现简单的客户端与服务器端通信
import java.io.InputStream;
import java.io.OutputStream;
import java.net.*;

public class Test{
    public static  void main(String[] args){
        if(args.length>0)
            server();
        else
            client();

    }
    //服务器端
    public static void server()
    {
        try {
            //创建一个服务器端套接字,绑定到端口6050上
            ServerSocket ss=new ServerSocket(6050);
            //监听连接请求,如果客户端请求连接,则接受连接,返回套接字s
            Socket s=ss.accept();
            //利用套接字获取输出流
            OutputStream os=s.getOutputStream();
            //利用套接字获取输入流
            InputStream is=s.getInputStream();
            //利用输出流向客户端发送数据
            os.write("Hello,this is server".getBytes());
            //利用输入流从网络上读取数据到数组bytes中
            byte[] bytes=new byte[100];
            int len=is.read(bytes);//返回实际读取的字节数
            //将读取的数据打印出来
            System.out.println(new String(bytes,0,len));
            os.close();
            is.close();
            s.close();
            ss.close();
        }
        catch (Exception e){
            e.printStackTrace();
        }
    }
    public static void client()
    {
        try {
            Socket socket=new Socket(InetAddress.getByName(null),6050);
            OutputStream outputStream=socket.getOutputStream();
            InputStream inputStream=socket.getInputStream();
            byte[] buf=new byte[100];
            int len=inputStream.read(buf);
            //打印读取的数据
            System.out.println(new String(buf,0,len));
            outputStream.write("Hello,this is client".getBytes());
            outputStream.close();
            inputStream.close();
            socket.close();
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}
//利用多线程实现一个服务器端对应多个客户端
import java.io.InputStream;
import java.io.OutputStream;
import java.net.*;
import java.util.Scanner;

public class Lesson10 extends Thread
{
    private Socket s;
    public Lesson10 (Socket s)
    {
        this.s=s;
    }

    public void run() {
        try{
            //利用套接字获取输出流
            OutputStream os=s.getOutputStream();
            //利用套接字获取输入流
            InputStream is=s.getInputStream();
            //利用输出流向客户端发送数据
            os.write("Hello,this is server".getBytes());
            //利用输入流从网络上读取数据到数组bytes中
            byte[] bytes=new byte[100];
            int len=is.read(bytes);//返回实际读取的字节数
            //将读取的数据打印出来
            System.out.println(new String(bytes,0,len));
            os.close();
            is.close();
            s.close();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public static  void main(String[] args){
        if(args.length>0)
            server();
        else
            client();

    }
    //服务器端
    public static void server()
    {
        try {
            //创建一个服务器端套接字,绑定到端口6050上
            ServerSocket ss=new ServerSocket(6050);
            while (true) {
                //监听连接请求,如果客户端请求连接,则接受连接,返回套接字s
                Socket s = ss.accept();
                new Lesson10(s).start();
            }
        }
        catch (Exception e){
            e.printStackTrace();
        }
    }
    public static void client()
    {
        try {
            Socket socket=new Socket(InetAddress.getByName(null),6050);
            OutputStream outputStream=socket.getOutputStream();
            InputStream inputStream=socket.getInputStream();
            byte[] buf=new byte[100];
            int len=inputStream.read(buf);
            //打印读取的数据
            System.out.println(new String(buf,0,len));
            outputStream.write("Hello,this is client".getBytes());
            outputStream.close();
            inputStream.close();
            socket.close();
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

注意:使用带缓冲的输出流会给网络通信造成一定的延迟

12、基于UDP(无连接的)的Socket编程:
在这里插入图片描述

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

public class UDPSocket {
    public static void main(String[] args){
        if(args.length>0)
            recv();
        else
            send();

    }
    public static void recv()
    {
        try{
            DatagramSocket datagramSocket=new DatagramSocket(6000);
            byte[] bytes=new byte[100];
            //指定数据包长度时不能超过数组的最大容量
            DatagramPacket datagramPacket=new DatagramPacket(bytes,100);
            datagramSocket.receive(datagramPacket);
            //DatagramPacket的getLength()方法返回实际接受数据长度
            System.out.println(new String(bytes,0,datagramPacket.getLength()));
            String string="Welcome you";
            //构造发送的数据包,通过DatagramPacket中的getAddress()方法和getPort()方法获取数据包的IP地址和发送端进程的端口号
            DatagramPacket dpSend=new DatagramPacket(string.getBytes(),string.length(),
                    datagramPacket.getAddress(),datagramPacket.getPort());
            datagramSocket.send(dpSend);
            datagramSocket.close();
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    public static void send(){
        try {
            DatagramSocket datagramSocket = new DatagramSocket();
            String str="Hello,this is hh!";
            DatagramPacket datagramPacket=new DatagramPacket(str.getBytes(),str.length(),
                    InetAddress.getByName(null),6000);
            datagramSocket.send(datagramPacket);
            byte[] bytes=new byte[100];
            DatagramPacket dpRecv = new DatagramPacket(bytes,100);
            datagramSocket.receive(dpRecv);
            System.out.println(new String(bytes,0,dpRecv.getLength()));
            datagramSocket.close();
        }catch (Exception e){
            e.printStackTrace();
        }

    }
}

数据报套接字不像TCP套接字要建立连接,但是当第一次发送数据成功就相当于建立了一个虚连接,双方之间都可以发送数据和读取数据。

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

import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.*;
import javax.swing.*;
import java.awt.event.*;

public class Download {
    public static void main(String[] args){
        JFrame jFrame=new JFrame("下载程序");
        jFrame.setSize(600,400);
        jFrame.setLocation(100,100);
        JPanel panel=new JPanel();
        JLabel label=new JLabel("Plase input URL:");
        final JTextField jTextField=new JTextField(30);
        panel.add(label);
        panel.add(jTextField);
        jFrame.getContentPane().add(panel,"North");
        final JTextArea jTextArea=new JTextArea();//文本区
        jFrame.getContentPane().add(jTextArea,"Center");
        JButton jButton=new JButton("Download");
        jFrame.getContentPane().add(jButton,"South");
        jButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String string=jTextField.getText();//获取文本域中输入的信息
                try {
                    URL url=new URL(string);//构造URL对象
                    //通过URL的openConnection()方法返回一个URLConnection对象,
                    //URLConnection是一个抽象类不能直接实例化;
                    URLConnection urlConnection=url.openConnection();
                    //将信息添加到文本区当中,getHost()方法获取url表示的主机名
                    jTextArea.append("Host:"+url.getHost());
                    //通过getProperty方法传递键获取行的分隔符,系统属性line.separator代表了行的分隔符
                    String line=System.getProperty("line.separator");
                    jTextArea.append(line);
                    //将端口号添加到文本区中,getDefaultPort()方法获取端口号
                    jTextArea.append("Port:"+url.getDefaultPort());
                    jTextArea.append(line);
                    //URLConnection类中的getContentType()方法获取内容的类型
                    jTextArea.append("ContentTypr:"+urlConnection.getContentType());
                    jTextArea.append(line);
                    //获取内容的长度
                    jTextArea.append("ContentLength:"+urlConnection.getContentLength());

                    InputStream inputStream=urlConnection.getInputStream();
                    InputStreamReader inputStreamReader=new InputStreamReader(inputStream);
                    //BufferedReader bufferedReader=new BufferedReader(inputStreamReader);
                    FileOutputStream fileOutputStream=new FileOutputStream("1.html");
                    //String string1;
                    //while ((string1=bufferedReader.readLine())!=null)
                    int data;
                    while ((data=inputStream.read())!=-1)
                    {
                        //fileOutputStream.write(string1.getBytes());//写入数据,按行读取
                        //fileOutputStream.write(line.getBytes());//写入行分隔符
                        fileOutputStream.write(data);//一个字节一个字节的读取
                    }
                    //bufferedReader.close();
                    inputStream.close();
                    fileOutputStream.close();
                }catch (Exception e1){
                    e1.printStackTrace();
                }

            }
        });
        jFrame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
       jFrame.show();
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值