网络编程(1)

1、网络编程的基础知识

Java程序可以非常方便的访问互联网上的HTTP服务、FTP服务等,并可以直接取得互联网上的远程资源,还可以向远程资源发送GET、POST请求。

1.1、网络的概念和分类

所谓计算机网络就是把分布在不同地理区域的计算机与专门的外部设备用通信线路互连成一个规模大、功能强的网络系统,从而使众多的计算机可以方便地互相传递信息、共享硬件、软件、数据信息等资源。

生活在今天的我们,没有网络那是相当可怕的,我们每天几乎都在用所谓的云计算、云服务、云备份、搜索引擎检索信息、即时通信、在线支付…

计算机网络有很多种,按照网络的传输介质划分:双绞线网、同轴电缆网、光纤网、卫星网等。还有无线传输的,例如Wife的传输介质是红外线,蓝牙的传输介质是无线电波,都是电磁波的一种。

如果按照网络的拓扑结构来划分,可以分为星型网络、总线网络、环线网络、树型网络、网状网络、混合型网络等。

在这里插入图片描述

按照规模来分类:

  1. 局域网(Local Area Network,LAN)是指在某一区域内由多台计算机互联成的计算机组。一般是方圆几千米以内。局域网可以实现文件管理、应用软件共享、打印机共享、工作组内的日程安排、电子邮件和传真通信服务等功能。局域网是封闭型的,可以由办公室内的两台计算机组成,也可以由一个公司内的上千台计算机组成。

  2. 城域网(Metropolitan Area Network,MAN)是在一个城市范围内所建立的计算机通信网,属宽带局域网。由于采用具有有源交换元件的局域网技术,网中传输时延较小,它的传输媒介主要采用光缆,传输速率在100兆比特/秒以上。MAN的一个重要用途是用作骨干网,通过它将位于同一城市内不同地点的主机、数据库,以及LAN等互相联接起来,这与WAN的作用有相似之处,但两者在实现方法与性能上有很大差别。

  3. 广域网(Wide Area Network, WAN),又称外网、公网,是连接不同地区局域网或城域网计算机通信的远程网。通常跨接很大的物理范围,所覆盖的范围从几十公里到几千公里,它能连接多个地区、城市和国家,或横跨几个洲并能提供远距离通信,形成国际性的远程网络。

那么什么是互联网、因特网、万维网呢?

凡是由能彼此通信的设备组成的网络就叫互联网,即使仅有两台机器(计算机、手机等),不论用何种技术使其彼此通信,都叫互联网,所以,互联网有广域网、城域网及局域网之分。国际标准的互联网写法是internet,字母i小写!

而因特网是互联网中的一种,它可不是仅有两台机器组成的网络,而是由上千万台设备组成的网络(该网络具备一定规模)。国际标准的因特网写法是Internet,字母I大写!

因特网是基于TCP/IP协议实现的,TCP/IP协议由很多协议组成,不同类型的协议又被放在不同的层,其中,位于应用层的协议就有很多,比如FTP、SMTP、HTTP。所以,因特网提供的服务一般包括有:www(万维网)服务、电子邮件服务(outlook)、远程登录(QQ)服务、文件传输(FTP)服务、网络电话等等。只要应用层使用的是HTTP协议,就称为万维网(World Wide Web)。

1.2、网络协议

不管处于那种网络,那么通信是网络最基本的要求,而计算机网络中实现通信必须有一些约定,即通信协议。对速率、传输代码、代码结构、传输控制步骤、出错控制等制定标准。

网络通信必须有硬件和软件方面的支持,由于世界上大型计算机厂商推出各自不同的网络体系结构,影响了网络通信的统一性,因此国际标准化组织ISO于1978年提出了著名的OSI(Open System Interconnection)开放系统互连参考模型。它把计算机网络分成物理层、数据链路层、网络层、传输层、会话层、表示层、应用层等七层。

● 应用层:网络服务与最终用户的一个接口。协议有:HTTP、FTP、SMTP、DNS、TELNET、HTTPS、POP3等等。

● 表示层:数据的表示、安全、压缩。格式有:JPEG、ASCll、DECOIC、加密格式等。

● 会话层:建立、管理、终止会话。对应主机进程,指本地主机与远程主机正在进行的会话

● 传输层:定义传输数据的协议端口号,以及流控和差错校验。协议有:TCP、UDP。

●网络层:进行逻辑地址寻址,实现不同网络之间的路径选择。协议有:ICMP、IGMP、IP(IPV4 IPV6)、ARP、RARP。

● 数据链路层:建立逻辑连接、进行硬件地址寻址、差错校验等功能。将比特组合成字节进而组合成帧,用MAC地址访问介质,错误发现但不能纠正。

● 物理层:建立、维护、断开物理连接。

而IP协议是一种非常重要的协议。IP(internet protocal)又称为互联网协议。IP的责任就是把数据从源传送到目的地。它在源地址和目的地址之间传送一种称之为数据包的东西,它还提供对数据大小的重新组装功能,以适应不同网络对包大小的要求。经常与IP协议放在一起的还有TCP(Transmission Control Protocol)协议,即传输控制协议,是一种面向连接的、可靠的、基于字节流的传输层通信协议。而通常我们说的TCP/IP协议,其实是指TCP/IP协议族,因为该协议家族的两个最核心协议:TCP(传输控制协议)和IP(网际协议),为该家族中最早通过的标准,所以简称为TCP/IP协议。

按照TCP/IP协议模型,网络通常被分为四层:网络访问层、互联网层、传输层和应用层。
在这里插入图片描述

1.3、IP地址

IP地址用于标识网络中的一个通信实体,这个通信实体可以是一台计算机,也可以是一台打印机,或者是路由器的一个端口。而在基于IP协议网络中传输的数据包,都必须使用IP地址来进行标识。

如同我们写信,发快递一样,要标明收件人的通信地址和发件人的通信地址,而邮政人员和物流快递员则通过该地址决定信件、包裹的去向。

IP地址是一个32位的整数,但为了便于记忆,通常把它分为4个8位的二进制数组成,每8位之间用圆点隔开,格式:X.X.X.X,其中每个X表示地址中的8位,用十进制[0,255]之间值表示,因此我们看到的IP常常是:222.222.88.104。

Internet委员会定义了5种IP地址类型以适合不同容量的网络,即A类~E类。其中A、B、C这3类由Internet NIC在全球范围内统一分配,D、E类为特殊地址。

在这里插入图片描述

IP地址还分为IPV4和IPV6。由于IPv4最大的问题在于网络地址资源有限,严重制约了互联网的应用和发展。IPv6是IETF(Internet Engineering Task Force)设计的用于替代现行版本IP协议(IPv4)的下一代IP协议,号称可以为全世界的每一粒沙子编上一个网址。IPv4和IPv6地址格式不相同,因此在很长一段时间里,互联网中出现IPv4和IPv6长期共存的局面。2012年6月6日,国际互联网协会举行了世界IPv6启动纪念日,这一天,全球IPv6网络正式启动。多家知名网站,如Google、Facebook和Yahoo等,于当天全球标准时间0点(北京时间8点整)开始永久性支持IPv6访问。2018年6月,三大运营商联合阿里云宣布,将全面对外提供IPv6服务,并计划在2025年前助推中国互联网真正实现“IPv6 Only”。 7月,百度云制定了中国的IPv6改造方案。8月3日,工信部通信司在北京召开IPv6规模部署及专项督查工作全国电视电话会议,中国将分阶段有序推进规模建设IPv6网络,实现下一代互联网在经济社会各领域深度融合。

IPv6的地址长度为128位,是IPv4地址长度的4倍,格式为X:X:X:X:X:X:X:X,其中每个X表示地址中的16位,以十六进制表示。

1.4、端口号

IP地址可以唯一的确定网络上的一个通信实体,但是一个通信实体可以有多个通信程序同时提供网络服务,此时还需要使用端口。IP地址就好比通信的街道和门牌号,我们通过IP地址可以找到房子,但是要具体找到某个人,还需要房间号或名字。

端口号是一个16位的整数,即在[0,65535]之间,通常它可以分为三类:

  1. 公认端口(Well-Known Ports)范围从0到1023,这些端口号一般固定分配给一些服务。比如21端口分配给FTP(文件传输协议)服务,25端口分配给SMTP(简单邮件传输协议)服务,80端口分配给HTTP服务。

  2. 注册端口(Registered Ports):端口号从1024到49151。它们松散地绑定于一些服务。例如:Tomcat(8080),JBOSS(8080),Oracle(1521),MySQL(3306),SQL Server(1433),QQ(1080)。

  3. 动态/私有端口(Dynamic and/Private Ports):端口的范围从49152到65535,这些端口号一般不固定分配给某个服务。只要运行的程序向系统提出访问网络的申请,那么系统就可以从这些端口号中分配一个供该程序使用。理论上,不应为服务分配这些端口。

然而实际生活中,要常人识记IP地址还是有些困难的,所以就有了域名。例如:网易的服务器IP地址是123.58.180.8,为了让大家便于记忆和访问,我们注册了域名:www.bdit.com。域名和IP地址是相对应的,网域名称系统(DNS,Domain Name System)是因特网的一项核心服务,它作为可以将域名和IP地址相互映射的一个分布式数据库,能够使人更方便的访问互联网,而不用去记住能够被机器直接读取的IP地址数串。

2、基本的网络API

2.1、使用InetAddress

此类表示互联网协议 (IP) 地址,它有两个子类Inet4Address和Inet6Address,分别对应IPV4和IPV6。InetAddress类没有提供公共的构造器,而是提供了如下几个静态方法来获取InetAddress实例。

● public static InetAddress getLocalHost()

● public static InetAddress getByAddress(byte[] addr)

● public static InetAddress getByName(String host)

InetAddress提供了如下几个常用的方法:

●public String getHostAddress():返回 IP 地址字符串(以文本表现形式)。

● public String getHostName():获取此 IP 地址的主机名

● public String getCanonicalHostName():获取此 IP 地址的完全限定域名

● public boolean isReachable(int timeout):测试是否可以达到该地址。

package com.bdit.ip;

import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.net.UnknownHostException;

public class TestInetAddress {
    public static void main(String[] args) throws Exception{
        InetAddress ip1 = InetAddress.getLocalHost();
        System.out.println(ip1);//Irene-PC/192.168.1.107

        InetAddress ip2 = InetAddress.getByName("www.bdit.com");
        System.out.println(ip2);//www.bdit.com/222.222.88.102

        byte[] ip = {(byte)222,(byte)222,88,102};
        InetAddress ip3 = InetAddress.getByAddress(ip);
        System.out.println(ip3);//输出ip而不是域名。如果这个IP地址不存在或DNS服务器不允许进行ip-->域名的映射,getHostName()方法就直接返回这个IP地址
    }
}

2.2、使用URL

URI(Uniform resource identifier):表示一个统一资源标识符 (URI) 引用,用来唯一的标识一个资源。

URL(Uniform Resource Locator):类 URL 代表一个统一资源定位符,它是指向互联网“资源”的指针。资源可以是简单的文件或目录,也可以是对更为复杂的对象的引用,例如对数据库或搜索引擎的查询。它是一种具体的URI,即URL可以用来标识一个资源,而且还指明了如何locate这个资源。URI不能用于定位任何资源,它的唯一作用是解析,而URL则包含一个可打开到达该资源的输入流。 URL的基本结构由5部分组成:

传输协议>://<主机名>:<端口号>/<文件名>#片段名

<传输协议>://<主机名>:<端口号>/<文件名>?参数列表

其中#片段名:即锚点,例如看小说,直接定位到章节

例如:http://java.sun.com/index.html#chapter1

参数列表格式:参数名=参数值&参数名=参数值…

例如: http://192.168.1.100:8080/helloworld/index.jsp?username=chai&password=123

URL构造方法:

  1. public URL (String spec):通过一个表示URL地址的字符串可以构造一个URL对象。例如:URL url = new URL (“http://www.
    bdit.com/”);

  2. public URL(URL context, String spec):通过基 URL 和相对 URL 构造一个 URL 对象。例如:URL downloadUrl = new URL(url,
    “download.html”)

  3. public URL(String protocol, String host, String file); 例如:new
    URL(“http”, “www.bdit.com”, “download.
    html");

  4. public URL(String protocol, String host, int port, String file); 例如: URL
    gamelan = new URL(“http”, “www.bdit.com”, 80, “download.html");

URL的常用方法:

  1. public String getProtocol():获取该URL的协议名

  2. public String getHost():获取该URL的主机名

  3. public String getPort():获取该URL的端口号

  4. public String getPath():获取该URL的文件路径,即tomcat的webapps目录下级目录名也就是资源路径名

  5. public String getFile():获取该URL的文件名

  6. public String getRef():获取该URL在文件中的相对位置

  7. public String getQuery():获取该URL的查询名

  8. public final InputStream openStream():返回一个用于从该连接读入的 InputStream。

package com.bdit.url;

import java.net.MalformedURLException;
import java.net.URL;

public class TestURL {
    public static void main(String[] args) throws MalformedURLException {
        URL url = new URL("http://www.baidu.com:80/index.html?keyword=java");
        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.getRef());
        System.out.println("查询名:" + url.getQuery());//注意如果存在锚点,那么查询名返回null,因为#后面全部当做锚点了
    }
}

案例:获取百度首页的资源

package com.bdit.url;

import java.io.InputStream;
import java.net.URL;

public class TestURLRead {
    public static void main(String[] args)throws Exception {
        URL url = new URL("http://www.baidu.com/index.html");
        /*html标签(格式化数据)、css:皮肤(美化数据)、js:互动(交互数据)、数据:*/
        InputStream input = url.openStream();
        byte[] data = new byte[1024];
        int len;
        while((len=input.read(data))!=-1){
            System.out.println(new String(data,0,len,"UTF-8"));
        }
        input.close();
    }
}

2.3、使用URLConnection

URL的方法openStream(),能从网络上读取数据,但是无法给服务器端发送数据,若希望给服务器端发送数据,则需要URLConnection。

它代表应用程序和 URL 之间的通信链接。此类的实例可用于读取和写入此 URL 引用的资源。通常,创建一个到 URL 的连接需要几个步骤:

  1. 通过 URL对象调用 openConnection 方法创建URLConnection连接对象。

  2. 处理设置参数和一般请求属性。

  3. 使用 connect 方法建立到远程对象的实际连接。

  4. 远程对象变为可用。远程对象的头字段和内容变为可访问。

URLConnection的常用方法:

● public void setDoOutput(boolean dooutput)如果打算使用 URL 连接进行输出,例如给服务器传递请求参数,则将 DoOutput 标志设置为 true;如果不打算使用,则设置为 false。默认值为 false。 必须在所有getXXX()和connect()方法之前。

● public String getContentEncoding():返回 content-encoding 头字段的值。

● public int getContentLength():返回 content-length 头字段的值。

● public String getContentType():返回 content-type 头字段的值。

● public long getDate():返回 date 头字段的值。

● public long getLastModified():返回 last-modified 头字段的值。结果为距离格林威治标准时间 1970 年 1 月 1 日的毫秒数。

● public String getHeaderField(String name):返回指定的头字段的值。

● public InputStream getInputStream()返回从此打开的连接读取的输入流。

● public OutputStream getOutputStream()返回写入到此连接的输出流。

package com.bdit.url;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;

public class TestURLConnection {
    public static void main(String[] args) throws Exception{
        URL url = new URL("http://localhost/web1/denglu");
        //通过 URL对象调用 openConnection 方法创建URLConnection连接对象
        URLConnection uc = url.openConnection();
        //处理设置参数
        uc.setDoOutput(true);
        //给服务器发送请求参数
        uc.getOutputStream().write("username=admin&password=123".getBytes());
        //使用 connect 方法建立到远程对象的实际连接。
        uc.connect();
        //获取资源
        InputStream is = uc.getInputStream();
        BufferedReader br = new BufferedReader(new InputStreamReader(is,"UTF-8"));
        String str;
        while((str=br.readLine())!=null){
            System.out.println(str);
        }
        br.close();
    }
}

2.4、Socket

通信的两端都要有Socket(也可以叫“套接字”),是两台机器间通信的端点。网络通信其实就是Socket间的通信。Socket可以分为:

  1. 流套接字(stream socket):使用TCP提供可依赖的字节流服务

  2. 数据报套接字(datagram socket):使用UDP提供“尽力而为”的数据报服务

  3. 【基于TCP的网络编程都是采用的流套接字,它是面向连接,提供可靠无差错的网络通信】

  4. 【基于UDP的网络编程是面向无连接,不可靠的网络通信,大多数网络会议软件都是采用的UDP协议】

在这里插入图片描述

Socket类的常用构造方法:

  1. public Socket(InetAddress address,int port):创建一个流套接字并将其连接到指定 IP 地址的指定端口号。

  2. public Socket(String host,int port):创建一个流套接字并将其连接到指定主机上的指定端口号。

Socket类的常用方法:

  1. public InputStream getInputStream():返回此套接字的输入流,可以用于接收消息

  2. public OutputStream getOutputStream():返回此套接字的输出流,可以用于发送消息

  3. public InetAddress getInetAddress():此套接字连接到的远程 IP 地址;如果套接字是未连接的,则返回 null。

  4. public InetAddress getLocalAddress():获取套接字绑定的本地地址。

  5. public int getPort():此套接字连接到的远程端口号;如果尚未连接套接字,则返回 0。

  6. public int getLocalPort():返回此套接字绑定到的本地端口。如果尚未绑定套接字,则返回 -1。

  7. public void close():关闭此套接字。套接字被关闭后,便不可在以后的网络连接中使用(即无法重新连接或重新绑定)。需要创建新的套接字对象。
    关闭此套接字也将会关闭该套接字的
    InputStream 和 OutputStream。

  8. public void shutdownInput():如果在套接字上调用 shutdownInput() 后从套接字输入流读取内容,则流将返回 EOF(文件结束符)。
    即不能在从此套接字的输入流中接收任何数据。

  9. public void shutdownOutput():禁用此套接字的输出流。对于 TCP 套接字,任何以前写入的数据都将被发送,并且后跟 TCP 的正常连接终止序列。
    如果在套接字上调用
    shutdownOutput() 后写入套接字输出流,则该流将抛出 IOException。 即不能通过此套接字的输出流发送任何数据。

注意:先后调用Socket的shutdownInput()和shutdownOutput()方法,仅仅关闭了输入流和输出流,并不等于调用Socket的close()方法。在通信结束后,仍然要调用Scoket的close()方法,因为只有该方法才会释放Socket占用的资源,比如占用的本地端口号等。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值