概述
Java是Internet上的语言,它从语言级上提供了对网络应用程序的支持,程序员能很容易开发常见的网络应用程序
Java提供的网络类库,可以实现无痛的网络链接,联网的底层细节被隐藏在Java的本机安装系统里,由JVM进行控制。并且Java实现了一个跨平台的网络库,程序员面对的是一个统一的网络编程环境。
计算机网络:把分布在不同地理区域的计算机与专门的外部设备用通信线路互连成一个规模大、功能强的网络系统,从而使众多的计算机可以方便地互相传递信息、共享硬件、软件、数据信息等资源
网络编程的目的:直接或间接地通过网络协议与其他计算机实现数据交换,进行通讯
网络编程中地两个主要问题:如何准确地定位网络上一台或多态主机;定位主机上地特定地应用。找到主机后如何可靠高效地进行数据传输。
通信双方的地址:
ip
端口号
一定的规则(即:网络通信协议。有两条参考模型)
OSI参考模型:模型过于理想化,未能在因特网上进行广泛应用
TCP/IP参考模型(或TCP/IP协议):事实上的国际标准
| 计算机网络分层模型 | ||
|---|---|---|
| OSI七层模型 | TCP/IP四层模型 | TCP/IP参考模型 |
| 应用层 | 应用层 | HTTP、FTP、Telnet、DNS... |
| 表示层 | ||
| 会话层 | ||
| 传输层 | 传输层 | TCP、UDP、... |
| 网络层 | 网络层 | IP、ICMP、ARP |
| 数据链路层 | 物理+数据链路层 | Link |
| 物理层 | ||
通信要素1:IP和端口号
IP
IP地址:InetAddress
唯一标识Internet上的计算机(通信实体)
本地回环地址(hostAddress):127.0.0.1 主机名(hostname):localhost
IP地址分类方式1:IPV4和IPV6
- IPV4:4个字节组成,4个0-255,大概42亿,30亿都在北美,亚洲4亿,2011年初已经用尽。以点分十进制标识,如192.168.0.1
- IPV6:128位(16个字节),写成8个无符号证书,每个整数用四个十进制为标识,数之间用冒号(:)分开,如
3ffe:3201:1401:1280:c8ff:fe4d:db39:1984 - IP地址分类方式2:公网地址(万维网使用)和私有地址(局域网使用),192.168.开头的就是私有地址,范围几位192.168.0.0-192.168.255.255,专门为组织机构内部使用
- 域名:www.baidu.com等
- 本机回路地址:127.0.0.1 代表本机 对应着localhost
- 如何实例化InetAddress:两个方法:getByName(String host)、getLocalHost();两个常用方法:getHostName()/getHostAddress()
特点:不易记忆。
public static void main(String[] args){
try{
//类似File
InetAddress inet1 = InetAddress.getByName("192.168.10.14");
System.out.println(inet1);
InetAddress inet2 = InetAddress.getByName("www.baidu.com");
System.out.println(inet2);
//获取本机
InetAddress inet4 = InetAddress.getLocalHost();
System.out.println(inet4);
}catch(UnkonwHostException e){
e.printStackTrace();
}
}
端口号
端口号表示正在计算机上运行的进程(程序)
- 不同的进程有不同的端口号
- 并规定为一个16位的整数 0-65535
- 端口分类:
公认端口:0-1023。呗预先定义的服务通信占用(如:HTTP占用端口号80,FTP占用端口21,Telnet占用端口23
注册端口:1024-49151。分配给用户进程或应用程序(如:Tomcat占用端口8080,Mysql占用端口3306,oracle占用端口1521等)
动态/私有端口:491452~65535
端口号与IP地址的组合可以得出一个网络套接字:Socket
网络通信要素二:网络协议
- 网络通信协议
计算机网络中实现通信必须有一些约定,即通信协议,对速率、传输代码、代码结构、传输控制步骤、出错控制等指定标准。 - 问题:网络协议太复杂
计算机网络通信涉及内容很多,比如指定源地址和目标地址,加密解密,压缩,解压缩,差错控制,流量控制,路由控制,如何实现如此复杂的网络协议呢? - 通信协议分层的思想
在制定协议时,把复杂成份分解成一些简单的成份,再将它们复合起来。最常用的复合方式是层次方式,即同层间可以通信、上一层可以调用下一层,而与再下一层不发生关系。各层互不影响,利于系统的开发和扩展。
TCP/IP协议簇
传输层协议有两个非常重要的协议:
- 传输控制协议TCP(Transmission Control Protocol)
- 用户数据报协议UDP(User Datagram Protocol)
TCP/IP以及两个主要协议:传输控制协议(TCP)和网络互联协议(IP)而得名,实际上是一组协议,包括多个具有不同功能且互为关联的协议
IP(Internet Protocol)协议是网络层的主要协议,支持网间互联的数据通信。
TCP/IP协议模型从更实用的角度出发,形成了高效的四层体系结构,即物理链路层、IP层、传输层和应用层。
TCP和UDP
TCP协议:
使用TCP协议前,须先建立TCP链接,形成传输数据通道
传输前,采用“三次握手”方式,点对点通信,是可靠的
TCP协议进行通信的两个应用进程:客户端、服务端
在连接中可进行大数据量的传输
传输完毕,需释放已建立的连接,效率低
UDP协议:
将数据、源、目的封装成数据包,不需要建立连接
每个数据报的大小限制在64K内
发送不管对方是否准备好吗,接收方收到也不确认,故是不可靠的
可以广播发送
发送数据结束无需释放资源,开销小,速度快
实现TCP的网络编程
//例子1:客户端发送信息给服务端,服务端将数据显示在控制台上
//客户端
@Test
public void client()throws IOException{
InetAddress inet = InetAddress.getByName("127.0.0.1");
Socket socket = new Socket(inet,8899);
OutputStream os = socket.getOutputStream();
os.write("你好,我是客户端".getBytes);
os.close();
socket.close();
}
//服务端
@Test
public void server(){
ServerSocket ss = new ServerSocket(8899);
Socket socket = ss.accept();
//InputStream is = socket.getInputStream();
//不建议这样写,可能会有乱码
//byte[] bufer = new byte[20];
//int len;
//while((len=is.read(buffer)!=-1){
//String str = new String(buffer,0,len);
//System.out.print(str);
//}
ByteArrayOutputStrem baos = new ByteArrayOutputStream();
byte[] buffer = new byte[5];
int len;
while((len=is.read(buiffer))!=-1){
baos.write(buffer,0,len);
}
System.out.println(baos.toString());
System.out.println("收到了来自于:"+socket.getInetAddress().getHostAddress()+"的数据")
//关闭资源
baos.close();
is.close();
socket.close();
ss.close();
}
//例题二:客户端发送文件给服务端,服务端将文件保存在本地
@Test
public void client(){
Socket socket = new Socket(InetAddress.getByName("127.0.0.1"),9090);
OutputStream os = socket.getOutputStream();
FileInputStream fis = new FileInputStream(new File("beauty.jpg"));
byte[] bufer = new byte[1024];
int len;
while((len=fis.read(buffer)!=-1){
os.write(buffer,0,len);
}
fis.close();
os.close();
socket.close();
}
@Test
public void server(){
ServerSocket ss = new ServerSocket("9090");
Socket socket = ss.accept();
InputStream is = socket.getInputStream;
FileOutputStream fos = new FileOutputStream(new File("beauti1.jpg"));
byte[] buffer = new byte[1024];
int len;
while((len=fos.read(buffer)!=-1){
fos.write(buffer,0,len);
}
fos.close();
is.close();
ss.close();
}