网络传输协议
InetAddress类
Socket类理解:
Socket常用方法
基于TCP的socket编程
基于UDP的socket编程
URL编程
总结
java网络编程
java天生就是支持网络的一种语言。java提供的网络类库,可以很容易的实现网络连接,而联网的底层细节被隐藏在java的本地安装系统里面,由JVM进行控制,java实现了跨平台的网络库,因此程序员面对的是一个统一的网络编程环境。
网络编程的两个问题:
1 如何准确的定位网络上一台或多台主机
2 如何可靠而且高效的进行数据传输。
IP地址和端口号
IP地址:唯一的标识Internet上的计算机
IP的两种表示方式:hostAddress 主机地址(俗称IP)
hostName 主机名(俗称域名)域名需要DNS域名服务器进行解析成IP地址,进行范围。
注 本地的回环地址:127.0.0.1 本地主机名:localhost
【了解】当浏览器发出域名的请求后,首先查找本地hosts,目录如下C:\Windows\System32\drivers\etc\hosts,查看是否有输入的域名地址,没有的话,再通过DNS服务器,解析域名,访问主机。
端口号:标识正在计算机上运行的程序。
1,不同的程序有不同的端口号;
2,端口号被规定为一个十六位的整数,0~65535。其中0~1023【Well-Known-Ports】被预先定义的服务通信占用(Mysql 占用3306,http占用80等)除非我们需要访问这些特定的服务,否则,我们就应该使用1024~65535【Dynamic Ports】这些端口中的某一个端口进行通信,以免发生端口冲突。
端口号和IP地址的组合得出一个网络套接字。
mysql:3306 tomcat:8080; ftp:21
http:80 oral:1521; telnet:23 ssh:22
java中的InetAddress类
-
InetAddress:位于java.net包下
1.InetAddress类用来代表IP地址。一个InetAdress的对象就代表着一个具体的IP地址
2.如何创建InetAddress的对象:InetAddress类的静态方法,
getByName(String host)
- 3.getHostName(): 获取IP地址对应的域名
getHostAddress():获取IP地址
InetAddress类没有提供对外的构造器,通常是通过如下的两个方法获取InetAddress类的实例。
getByName(String host) 在给定主机名的情况下确定IP地址,并返回InetAddress类的实例。参数可以是域名或者IP的字符串形式。
getByAddress(byte[] address) 在给定IP地址的情况下返回InetAddress类的实例。
getLocalHost()返回本地主机的InetAddress类的一个实例。
getHostAddress() 返回主机 IP地址的字符串形式。
getHostName() 返回主机 域名的字符串形式
isReachable(int timeout)在 timeout(毫秒)时间内,该主机是否可以访问。
getCanonicalHostName() 返回该主机的完全限定名 字符串形式。
数据传输封装模型:
网络传输通信协议
网络通信协议是一种标准,用来规范对传输速率,传输代码,代码结构,传输控制步骤,出错控制等。
通信协议的分层思想:
节点之间的联系很复杂,在制定协议的时候,把复杂的成分分解成若干个简单的成分,然后再将其复合起来。而最常用的复合方式是
层次方式,即同层之间可以通信,上一层可以调用下一层,而与再下一层不发生关系,各层之间互不影响,利于系统的开发和拓展。
基于对以上通信协议的认识,在传输层协议中两个最常用的协议:
1传输控制协议TCP(Transmission Control Protocol)
2用户数据包协议 UDP(User Datagram Protocol)
TCP协议:
使用TCP协议前,必须先建立TCP连接,形成传输数据通道
传输前,采用“三次握手”的方式,可靠性高
TCP协议进行通信的两个应用进程 客户端 & 服务器端
在连接中可以进行大数据量的传输
传输完毕,需要释放已经建立的链接,效率低
UDP协议:
将数据,源,目的封装成数据包,不需要建立连接
每个数据包的大小限制在64k内
因为无需连接,故而不可靠
发送数据包结束时,无需释放资源,速度快。
Socket 理解:
Socket是一组端口号与IP地址的组合。
利用Socket开发网络应用程序已被广泛采用,故而成为一种标准。
通信的两端都要有Socket。
网络通信其实就是Socket之间的通信。
Socket允许程序把网络连接当成一个流,数据在两个Socket之间通过IO传输。
一般主动发起通信的应用程序属于客户端Client,等待通信请求的一端数据服务器端Server。
基于Socket的TCP编程流程:
Socket类的常用方法
InetAddress getLocalAddress() 返回本地Socket中的InetAddress 对象。
InetAddress getInetAddress() 返回对方Socket 中的InetAddress 对象。
int getLocalPort() 返回本地Socket 中的端口
int getPort() 返回对方Socket 中的端口
void close() throws IOException 关闭Socket,不可在以后的网络链接中使用,除非创建新的Socket
InputStream getInputStream() throws IOException 获取与Socket相关联的字节输入流,用于从Socket中读数据。
OutputStream getOutputStream() throws IOException 获取与Socket相关的字节输出流,用于从Socket中写入数据。
基于Socket的TCP编程
1创建Socket:根据指定服务器的ip和端口构造Socket类对象。若服务器端响应,则建立客户端到服务器的通信线路,若连接失败,则出现异常。
2 打开连接到Socket的输入/输出流:使用 Socket对象的
getInputStream()方法获得输入流,使用getOutputStream()方法获得输出流。
3,按照一定的协议对Socket进行读写操作:通过输入流读取服务器放入线路的信息(但不能读取自己放入线路的信息),通过输出流将信息写入线路。
4,关闭Socket,断开客户端到服务端的连接,释放线路。
具体实现的部分代码:
客户端程序可以使用Socket类创建对象,创建的同时会自动向服务器方发起连接。
Socket的构造方法是:Socket(String host,int port)throws UnknownHostException,IOException
向服务器(域名是host。端口号为port)发起TCP连接,若成功,则创建Socket对象,否则抛出异常。
Socket(InetAddress address,int port)throws IOException:根据InetAddress对象所表示的IP地址以及端口号port发起连接。 客户端建立Socket对象的过程就是向服务器发出套接字连接请求
Socket s = new Socket(“192.168.40.165”,9999);
OutputStream out = s.getOutputStream(); out.write(“hello”.getBytes());
s.close();
服务器端四个基本的步骤:
1,调用 ServerSocket(int port) :创建一个服务器端套接字,并绑定到指定端口上。用于监听客户端的请求。此时如下代码可能发生IOException异常。
ServerSocket ss = new ServerSocket(9999);
2,调用 accept():监听连接请求,如果客户端请求连接,则接受连接,返回通信套接字对象。接受客户的套接字也容易发生IOException异常。注意accept()方法返回一个Socket对象,但是这个方法不会立刻返回,该方法会阻塞服务器端当前线程的执行,直到客户端请求建立 套接字连接 。
Socket s = ss.accept (); 注:ServerSocket 对象可以调用setSoTimeout(int timeout)方法设置超时值(单位毫秒),当ServerSocket对象调用accept()方法阻塞的时间一旦超过 timeout 就会出发 SocketTimeOutException
3,调用Socket类对象的getOutputStream() 和 getInputStream ()获取输出流和输入流,开始网络数据的发送和接收。
InputStream in = s.getInputStream();
byte[] buf = new byte[1024];
int len;
while((len = in.read(buf)) != -1){
String str = new String(buf,0,len);
System.out.print(str)}
4,关闭ServerSocket和Socket对象:客户端访问结束,关闭通信套接字。
in.close();
s.close(); ss.close();
备注:
ServerSocket 对象负责等待客户端请求建立套接字连接,也就是说,服务器必须事先建立一个等待客户请求,才建立套接字连接的ServerSocket对象。 所谓“接收”客户的套接字请求,就是accept()方法会返回一个 Socket 对象注意:
需要注意的是,从套接字连接中读取数据与从文件中读取数据有着很大的不同,尽管二者都是输入流,从文件中读取数据时,所有的数据都已经存在文件中,而使用套接字连接时,可能存在另一端的数据发送过来之前,就已经开始试着读取了,这就会堵塞本线程,直到该读取方法成功读取到信息,本线程才继续执行后续的操作。
建立连接之后,服务器端 套接字对象 可以调用getInetAddress()方法获取一个包含客户端IP的InetAddress对象。同样客户端也可以调用getInetAddress()方法返回一个包含服务器端IP的InetAddress对象。
套接字对象调用close()方法可以关闭双方的套接字连接对象的时候,只要一方关闭连接,就会导致对方发生IOException异常。
UDP网络通信
类 DatagramSocket 和 DatagramPacket 实现了基于 UDP 协议网络程序。 UDP数据报通过 数据报套接字 DatagramSocket 发送和接收,系统不保证UDP数据报一定能够安全送到目的地,也不能确定什么时候可以抵达。 DatagramPacket 对象封装了UDP数据报,在数据报中包含了发送端的IP地址和端口号以及接收端的IP地址和端口号。 UDP协议中每个数据报都给出了完整的地址信息,因此无须建立发送方和接收方的连接
UDP传输流程: 1,创建DatagramPacket对象,DatagramPacket类将数据打包,创建的DatagramPacket对象称为数据报,其构造器如下:
DatagramPacket(byte[] data,int len,InetAddress add, int port)
DatagramPacket(byte[],int offset,int length,InetAddress add,int port)
数据包对象包含以下特征:1,含有data数组指定的数据2,该数据包将发送到目标地址是add,目标端口号是port的主机上,其中第二个构造器创建的数据包对象含有数据data从offset开始指定长度的数据。
备注:DatagramPacket对象调用
public int getPort()方法获取数据报的目标端口号,
public InetAddress getAddres()方法获取目标地址
public byte[] getData()方法获取数据报中的数据。
2创建DatagramSocket对象,该对象负责发送数据报。
调用DatagramSocket类的无参构造器,如下
DatagramSocket mailOut = new DatagramSocket();
mailOut.send(package); 3创建DatagramSocket对象,负责接收数据报报DatagramSocket mailIn = new DatagramSocket(int port);
其中参数必须与待接收的数据报的端口号相同。
4创建待接收的数据报DatagramPacket对象,
调用其如下构造器建立数据包:DatagramPacket (byte[] data,int length);数据报将接受长度是length的数据放入byte数组data中。
byte[] data = new data[1024];
int length = 90;
DatagramPacket inpacket = new DatagramPacket(data,length);
5,调用DatagramSocket对象的receive(DatagramPacket inpacket)方法。
mailIn.receive(inpacket);注:receive()方法可能会阻塞线程,直到收到数据报datagrampacket。数据报对象可以调用getPort()方法获取所接收的数据报从远程主机的哪个端口发出,即数据包的始发端口号,同理,调用getInetAddress()方法可以获取数据包的始发地址。数据包长度不要超过8192KB。
处理接收的数据:
String str = new String(inPacket.getData(),0,inPacket.getLength());
System.out.println(str);
6关闭Socket对象
注意:发送端与接收端是两个独立的运行程序,线程独立。
URL编程
URL的基本构成:
<传输协议>://<主机名>:<端口号>/<文件名>例如: http://192.168.1.100:8080/helloworld/index.jsp
为了表示URL,java.net 中实现了类 URL。我们可以通过下面的构造器来初始化一个 URL 对象: public URL (String spec):通过一个表示URL地址的字符串可以构造一个URL对象。
例如:URL url = new URL ("http://www. atguigu.com/");
public URL(URL context, String spec):通过基 URL 和相对 URL 构造一个 URL 对象。
例如:URL downloadUrl = new URL(url, “download.html")
public URL(String protocol, String host, String file);
例如:new URL("http", "www.atguigu.com", “download. html");
public URL(String protocol, String host, int port, String file);
例如: URL gamelan = new URL("http", "www.atguigu.com", 80, “download.html");
类URL的构造方法都声明抛出非运行时异常,必须要对这一异常进行处理,通常是用 try-catch 语句进行捕获。 一个URL对象生成后,其属性是不能被改变的,但可以通过它给定的方法来获取这些属性:
public String getProtocol() 获取该URL的协议名
public String getHost() 获取该URL的主机名
public String getPort() 获取该URL的端口号
public String getPath() 获取该URL的文件路径
public String getFile() 获取该URL的文件名
public String getQuery() 获取该URL的查询名
InputStream openStream():①打开到此URl的连接,返回从该连接读入的InputStream。
URLConnection openConnection() :返回与URL的连接对象
若希望输出数据,例如向服务器端的 CGI (公共网关接口Common Gateway Interface 的简称,是用户浏览器和服务器端的应用程序进行连接的接口)程序发送一些数据,则必须先与URL建立连接,然后才能对其进行读写,此时需要使用 URLConnection 。
URLConnection:表示到URL所引用的远程对象的连接。
与一个URL建立连接时,首先要在一个 URL 对象上通过方法 openConnection() 生成对应的 URLConnection 对象。
如果连接过程失败,将产生IOException
URL netchinaren = new URL (“http://www.atguigu.com/index.shtml“); URLConnectonn con = netchinaren.openConnection( );
通过URLConnection对象获取的输入流和输出流,即可以与现有的CGI程序进行交互。
public Object getContent( ) throws IOException
public int getContentLength( )
public String getContentType( )
public long getDate( )
public long getLastModified( )
public InputStream getInputStream( )throws IOException
public OutputSteram getOutputStream( )throws IOException
总结
位于网络中的计算机具有唯一的IP地址,这样不同的主机可以互相区分。 客户端-服务器是一种最常见的网络应用程序模型。
服务器是一个为其客户端提供某种特定服务的硬件或软件。客户机是一个用户应用程序,用于访问某台服务器提供的服务。
端口号是对一个服务的访问场所,它用于区分同一物理计算机上的多个服务。
套接字用于连接客户端和服务器,客户端和服务器之间的每个通信会话使用一个不同的套接字。
TCP协议用于实现面向连接的会话。Java 中有关网络方面的功能都定义在 java.net 程序包中。
Java 用 InetAddress 对象表示 IP 地址,该对象里有两个字段:主机名(String) 和 IP 地址(int)。
类 Socket 和 ServerSocket 实现了基于TCP协议的客户端-服务器程序。
Socket是客户端和服务器之间的一个连接,连接创建的细节被隐藏了。这个连接提供了一个安全的数据传输通道,这是因为 TCP 协议可以解决数据在传送过程中的丢失、损坏、重复、乱序以及网络拥挤等问题,它保证数据可靠的传送。
类 URL 和 URLConnection 提供了*网络应用。URL 的网络资源的位置来同一表示 Internet 上各种网络资源。通过URL对象可以创建当前应用程序和 URL 表示的网络资源之间的连接,这样当前程序就可以读取网络资源数据,或者把自己的数据传送到网络上去。