Java学习笔记—第十二章 Java网络编程入门

第十二章  Java网络编程入门

  1. Java提供的三大类网络功能:

    (1)URL和URLConnection:三大类中最高级的一种,通过URL网络资源表达方式,可以很容易确定网络上数据的位置。利用URL的表示和建立,Java程序可以直接读入网络上所放的数据,或把自己的数据传送到网络的另一端。

    (2)Socket:又称“套接字”,用于描述IP地址和端口(在Internet中,网络中的每台主机都有一个唯一的IP地址,而每台主机又通过提供多个不同端口来提供多种服务)。在客户/服务器网络中,当客户机中运行的应用程序(如网页浏览器)需要访问网络中的服务器时,客户机会被临时分配一个Socket,然后它会通过服务器的Socket向服务器发出请求。简而言之,网络中的数据的发送和接收都是通过Socket来完成的,Socket就像一个文件句柄(读写文件时的一个唯一的顺序号),用户可以通过读写Socket来完成客户机、服务器之间的通信。

    (3)Datagram:三大类中最低级的一种。其他网络数据传送方式都假想在程序执行时建立一条安全稳定的通道,但是以Datagram方式传送数据时,只是把数据的目的地记录在数据包中,然后就直接放在网络上进行传输。系统不保证数据一定能安全送达,也不能确定什么时候可以送到。也就是说,Datagram不能保证传送质量。

  2. 了解Java网络编程基础知识

    (1)网络编程中有两个主要问题:如何准确定位网络上的一台或多台主机,以及找到主机后如何可靠地、高效地进行数据传输。在TCP/IP网络协议中,IP地址可以唯一确定Internet上的一台主机,而TCP则提供可靠的数据传输机制。

    (2)TCP/IP协议(传输控制协议/因特网互联协议  网络通信协议)

    TCP/IP协议是Transmission Control Protocol/Internet Protocol的缩写,是Internet最基本的协议,是供已连接因特网的计算机进行通信的通信协议。其定义了电子设备(如计算机)如何连入因特网,以及数据如何在它们之间传输的标准。TCP/IP协议由网络层IP协议和传输层的TCP协议组成。

    计算机网络通信划分为七层,自下而上分别是:物理层,数据链路层,网络层,传输层,会话层,表示层,应用层。每一层都提供了不同的网络协议。

    TCP/IP使用客户端/服务器模式进行通信,且通信是点对点的,即通信是在网路中的两台主机之间进行的。TCP协议为传输控制协议,负责聚集信息或把文件拆分成更小的包。这些包通过网络传送到接收端的TCP层,接收端的TCP层把包还原为原始文件。IP协议是网际协议,负责处理每个包的地址部分,使这些包能正确到达目的地。网络上的网关计算机根据信息的地址来进行路由选择。即使来自同一文件的分包路由也有可能不同,但最后会在目的地汇合。

  3. TCP协议与UDP协议(传输层)

    (1)TCP协议:面向连接,可靠传输。客户端与服务器之间必须先建立连接才能进行通信。得到一个顺序的、无差错的数据流。可以传输大容量数据,并确保服务器正确地接收到客户端发送的全部数据。

    (2)UDP协议:User Datagram Protocol(用户数据报协议),一种面向无连接,不可靠的传输协议。它将信息包装成数据报进行传输,数据报中包含完整的源地址或目的地址。不能保证数据报是否到达目的地、到达目的地的时间以及内容的正确性。传输数据大小限定在64KB之内。

  4. IP地址

    Java中用InetAddress类来描述IP地址。这个类没有公共的构造方法,但是它提供了三个用来获得InetAddress对象的静态方法。分别是:

    InetAddress getLocalHost():返回一个本地主机的InetAddress对象。

    InetAddress getByName(String host):返回主机名host指定的InetAddress对象。

    InetAddress[] getAllByName():对于某个多IP地址主机,可用该方法得到一个IP地址数组。

    此外,InetAddress类还提供了以下方法:

    String getHostAddress();返回IP地址字符串。

    String getHostName();返回主机名。

    例如:

    public class InetAddressTest{

    public static void main(String[] args){

    InetAddress ia;

    ia = InetAddress.getLocalHost();   //获得本地主机的InetAddress对象

    String localHostAddress = ia.getHostAddress(); //获得本地主机IP地址

    String localHostName = ia.getHostName()  //获得本地主机名

    ia = InetAddress.getByName("www.baidu.com");  //获得百度网主机的InetAddress对象

    String bdHostAddress = ia.getHostAddress();  //获取百度网主机地址

    String bdHostName = ia.getHostName();        //获取百度网主机名

    }

    }

  5. 端口

    端口是为了在一台主机上提供更多的网络资源而采取的一种手段。只有通过IP地址和端口号才能唯一地确定网络通信中的进程。端口用端口号来标记,端口号用0~65535的整数表示。

  6. 使用URL访问网络资源

    (1)URL:Uniform Resource Locator(统一资源定位符),对Internet资源的一个引用。大多数情况下,资源表示为一个文件,如一个HTML文档,一个图像文件,或一个声音片段等。因此,可以将URL理解为一个Internet资源地址。通用格式如下:

    <PROTOCOL>://<HOSTNAME:PORT>/<PATH>/<FILE>

    PROTOCOL表示Internet协议,常用的有HTTP、FTP、SMTP等。HOSTNAME表示资源所在的Internet主机名。主机名和IP地址是一一对应的,通过域名解析可以由主机名得到IP地址。PORT表示端口号,每一个Internet协议都有自己对应的端口号。PATH和FILE分别表示资源的路径名和文件名。

    (2)创建URL对象

    Java中可以使用URL类访问Internet资源。URL类的构造方法如下:

    a. URL(String spec):使用表示URL地址的字符串spec创建URL对象。例如:

    URL url = new URL("http://www.sina.com.cn");

    b. URL(URL baseURL,String relativeURL):使用绝对地址baseURL与相对地址relativeURL创建URL对象。例如:

    URL baseURL = new URL("http://www.base.edu.cn");

    URL url = new URL(baseURL,"/library/library.htm");

    c. URL(String protocol,String hostName,int port,String fileName):使用网络协议protocol、主机名hostName、端口号port、文件名fileName创建URL对象。例如:

    URL url = new URL("http","www.baidu.com","80","/library/library.htm");

    d. URL(String protocol,String hostName,String fileName):使用网络协议protocol、主机名hostName、文件名fileName创建URL对象。例如:

    URL url = new URL("http","www.baidu.com","/library/library.htm");

    备注:URL类的构造方法会抛出非运行时异常MalformedURLException,程序需要对此进行处理。

  7. 直接通过URL对象读取内容

    成功建立一个URL对象后,可以调用openStream()方法从网络资源中读取内容。例如:

    public class OpenStreamTest{

    public static void main(String[] args){

    try{

    URL sina = new URL("http://www.sina.com.cn/");

    DataInputStream dis = new DataInputStream(sina.openStream());

    String readLine;

    while((readLine = dis.readLine())!=null){

    System.out.print(readLine);

    }

    dis.close();

    }catch(MalformedURLException me){

    System.out.print("MalformedURLException:"+me);

    }catch(IOException ioe){

    System.out.print("IOException:"+ioe);

    }

    }

}

8. 建立一个URL连接并从中读取内容

通过URL类的openStream()方法,只能从网络资源中读取数据。如果想同时对数据进行读写操作,则必须利用URLConnection类建立一个URL连接。当与一个URL对象建立连接时,首先要通过URL对象的openConnection()方法生成URLConnection对象。URLConnection对象表示Java程序和URL对象在网络上的通信连接。如果连接过程失败,将会产生IOException。例如:

public class URLConnectionTest{

public static void main(String[] args){

try{

URL baidu = new URL("http://www.baidu.com/");

URLConnection conn = baidu.openConnection();

//创建数据输入流

DataInputStream dis = new DataInputStream(baidu.getInputStream);

String inputLine;

while((inputLine = dis.readLine())!=null){

System.out.print(inputLine);

}

dis.close();

}catch(MalformedURLException me){

System.out.print("MalformedURLException:"+me);

}catch(IOException ioe){

System.out.print("IOException:"+ioe);

}

}

}

9. 使用Socket进行网络通信

在应用层通过传输层进行数据通信时,TCP或UDP协议会遇到同时为多个应用程序进程提供并发服务的问题。多个TCP连接或多个应用程序进程可能需要通过同一个端口传输数据。为了区别不同的应用程序进程或连接,计算机操作系统为应用程序与TCP/IP协议交互提供了称为套接字(Socket)的接口。每个Socket由IP地址、传输层协议(TCP或UDP)、端口号三个参数唯一确定。

使用Socket进行服务器/客户端的通信时,可以分为三个步骤:服务器监听,客户端请求,连接确认。

(1)服务器监听:服务器端Socket实时监听某个端口是否有连接请求。

(2)客户端请求:指由客户端的Socket提出连接请求,要连接的目标是服务器端的Socket。客户端的Socket首先需要描述它要连接的服务器端的Socket,指出服务器端Socket的IP地址和端口号,然后便可以向服务器端发送连接请求。

(3)连接确认:当服务器端的Socket监听到或者接收到客户端Socket的连接请求时,就响应客户端的请求,并建立一个新的线程,然后把服务器端的Socket的描述发送给客户端。一旦客户端确认了此描述,一个连接便建立起来了。而服务器端Socket继续处于监听状态,并接收其他客户端Socket的连接请求。

(4)常见的Socket主要分为两种:

a. 流式Socket:一种基于TCP协议的通信,即在通信开始之前先由通信双方确认身份并建立一条连接通道,然后通过这条通道传输数据。

b. 数据报Socket:一种基于UDP协议的通信,无需通信双方建立连接,而是直接将信息打包传向指定的目的地。

(5)流式Socket编程

java.net包中定义了Socket类和ServerSocket类,它们是实现流式Socket通信的主要工具。创建Socket对象就创建了一个客户端与服务器端的连接,而创建一个ServerSocket对象就创建了一个监听服务。

 a. Socket类:通过构造一个Socket对象可以建立客户端与服务器的连接。Socket类的构造方法如下:

Socket(String host,int port)

Socket(InetAddress address,int port)

Socket(InetAddress address,int port,InetAddress localAddr,int localPort)

其中,host、port和address分别表示连接主机的主机名、端口号和IP地址;locaAddr表示本地主机的IP地址;localPort表示本地主机端口号。例如:

Socket mySocket = new Socket("www.sina.com",3000);

备注:每一个端口号提供一种特定的服务,只有给出正确的端口,才能获得相应的服务。0~1023的端口号为系统保留,例如,http服务的端口号为80,telenet服务的端口号为23,ftp服务端口号为21。

创建一个新的Socket对象后,就可以使用其getInputStream()方法获得一个InputStream流,然后可以通过InputStream对象从某个主机接收信息;而使用getOutputStream()可以获得一个OutputStream对象,利用它可以发送信息到某个主机。例如:

public class GetDayTime{

public static void main(String[] args){

try{

Socket socket = new Socket("stdtime.gov.hk",13);

BufferedReader br = new BufferedReader(new                                                                      InputStreamReader(socket.getInputStream()));

String daytime = br.readLine();

System.out.println("DayTime received:"+daytime);

socket.close();

}catch(IOException e){

System.out.println("ERROR:"+e);

}

}

}

b. ServerSocket类

ServerSocket类表示通信双方中的服务器,它可以监听客户端发送的连接请求并进行处理。将服务器所监听的端口号传递给ServerSocket的构造方法,就可以创建一个ServerSocket对象。ServerSocket类的构造方法如下:

ServerSocket(int port);

ServerSocket(int port,int count);

其中,port表示端口号,count表示服务器所能支持的最大连接数。例如:

ServerSocket serverSocket = new ServerSocket(5000);

这里指定服务器监听的端口号是5000。当创建一个ServerSocket对象后,就可以调用accept()方法接受来自客户端的请求。其格式为:

Socket socket = serverSocket.accept();

ServerSocket对象的accept()方法会使服务器端的程序一直处于阻塞状态,直到捕获一个来自客户端的请求,并返回一个Socket类的对象来处理与客户端的通信。

当需要结束监听时,可以使用如下语句关闭这个ServerSocket对象:

serverSocket.close();

 (6)数据报Socket编程

java.net包中提供了DatagramPacket和DatagramSocket类用来支持无连接的数据报Socket通信。DatagramSocket类用于在程序之间建立传送数据报的通信连接,DatagramPacket类则用于存储数据报等信息。

 a. DatagramSocket类:构造方法如下:

DatagramSocket();

DatagramSocket(int port);

DatagramSocket(int port,InetAddress localAddr);

其中,port表示端口号;localAddr表示本地地址。

DatagramSockt类构造方法会抛出非运行时异常SocketException,程序需要对此进行处理。

 b. DatagramPacket类:

用数据报方式编写Client/Server程序时,无论在客户端还是服务器,都首先需要建立一个DatagramSocket对象,用来接收或发送数据报,而DatagramPacket对象是数据报传输的载体。构造方法如下:

DatagramPacket(byte[] buf,int length);

DatagramPacket(byte[] buf,int length,InetAddress address,int port);

其中,字节数组buf中存放欲发送或接收的数据报,length表示数据报的长度,address和port表示数据报发送的目的地和主机端口号。

在客户端或服务器端接收数据之前,应该采用DatagramPacket类的第一种构造方法创建一个DatagramPacket对象,然后调用DatagramSocket类的receive()方法等待数据报的到来。例如:

DatagramSocket socket = new DatagramSocket();

DatagramPacket packet = new DatagramPacket(buf,256);

socket.receive();

在发送数据之前,需要使用DatagramPacekt类的第二种构造方法创建一个新的DatagramPacket对象,即要指明数据报发送的目的地址和端口号。发送数据报通过DatagramSocket类的send()方法实现。例如:

DatagramSocket socket = new DatagramSocket();

DatagramPacket packet = new DatagramPacket(buf,length,address,port);

socket.send(packet);

时间: 05-07

Java学习笔记—第十二章 Java网络编程入门的相关文章

java学习笔记(十五)java网络编程

OSI模型分为七层(从下到上):物理层.数据链路层.网络层.传输层.会话层.表示层.应用层. 不同主机之间的相同层次称为对等层.对等层之间互相通信需要遵守一定的规则,称之为协议,我们将某个主机上运行的某种协议的集合称为协议栈.主机正是利用这个协议栈来接收和发送数据的. TCP/IP模型:网络接口层.网络互连层.传输层.应用层. 在网络编程中需要注意的问题包括: 1.是如何找到网络上的主机上的要进行通讯的程序: 2.是找到了主机上的程序后如何传输数据. 端口号:是一组16位的无符号二进制数,每个端

《JAVA编程思想》学习笔记——第十二章 通过异常处理错误

Java的基本理念是 "结构不佳的代码不能运行" 发现错误的理想时机是在编译阶段,也就是在你试图运行程序之前.然而,编译期间并不能找出所有的错误,余下的问题必须在运行期间解决.这就需要错误源能通过某种方式,把适当的信息传递给某个接收者----该接收者将知道如何正确处理这个问题. 异常情形是指阻止当前方法或作用域继续执行的问题. 当抛出异常后,有几件事会随之发生.首先,同Java中其它对象的创建一样,将使用new在堆上创建异常对象.然后,当前的执行路径被终止,并且从当前环境中弹出对异常对

JAVA学习笔记(三十二)- 字符流 FileReader &amp; FileWriter

标题 import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream;

JAVA学习笔记(五十二)- 开发DAO层的经典实现

StudentDAO接口,定义学生相关的操作 /* * StudentDAO接口,定义学生相关的操作 */ public interface StudentDAO { //添加学生 public void addStudent(Student stu); //删除学生 public void deleteStudent(int id); //修改学生 public void updateStudent(Student stu); //查询所有学生 public List<Student> ge

java学习笔记(十二)多线程编程

并发编程:可以让多个任务同时运行的编程方式. 进程:一个正在运行的程序,有自己独立的一块内存空间,每一个进程的内部数据和状态都是完全独立的.可同时运行两个或更多的程序. 线程:每一个任务称为一个线程,在一个程序内运行多线程的程序称为多线程程序. 线程是进程内部单一的一个顺序控制流,是最小处理单位. 创建线程: 1.继承Thread类,重写run()方法,在run()方法中编写要执行的代码. 先创建Thread对象,打点调用start()启动线程. 2.实现Runable接口,只有run()方法.

JAVA学习笔记(四十二)-生产者消费者模型

wait().notify() /* * wait().notify() * * 1.两个方法都只能在synchronized代码块中执行,因为要对持有锁的线程操作,只有同步中才有锁 * 2.两个方法在操作同步中的线程时,必须要标识所操作线程持有的对象锁 * 3.等待和唤醒必须是同一个对象锁 */ public class Test05 { public static void main(String[] args) { MyThread3 mt=new MyThread3(); Thread

《深入Java虚拟机学习笔记》- 第5章 Java虚拟机

一.JVM的生命周期 当启动一个Java程序时,一个Java虚拟机实例就诞生了:当该程序关闭退出时,这个Java虚拟机也就随之消亡: JVM实例通过调用某个初始类的main方法来运行一个Java程序:这个main方法必须是public.static的,而且返回值必须是void:任何一个拥有这样的main方法的类都可以作为Java程序运行的起点: Java程序初始类中的main方法,将作为该程序初始线程的起点,其它任何线程都是由这个初始线程启动的: 守护线程和非守护线程 守护线程通常是由虚拟机自己

“全栈2019”Java多线程第四十二章:获取线程与读写锁的保持数

难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多线程第四十二章:获取线程与读写锁的保持数 下一章 "全栈2019"Java多线程第四十三章:查询是否有线程在等待读写锁 学习小组 加入同步学习小组,共同交流与进步. 方式一:关注头条号Gorhaf,私信"Java学习小组". 方式二:关注公众号Gorhaf,回复&quo

疯狂JAVA讲义---第十二章:Swing编程(五)进度条和滑动条

http://blog.csdn.net/terryzero/article/details/3797782 疯狂JAVA讲义---第十二章:Swing编程(五)进度条和滑动条 标签: swing编程java任务timerstring 2009-01-16 21:12 6722人阅读 评论(0) 收藏 举报  分类: J2SE(63)  版权声明:本文为博主原创文章,未经博主允许不得转载. 前几天讲了Swing基本的控件,今天开始讲特殊控件.一天讲2个吧,首先讲用JProgressBar,Pro