网络编程的目的,就是直接或间接的通过网络协议与其他计算机实现数据交换,进行通讯。
Java是 Internet 上的语言,提供了对网络应用程序的支持。Java提供的网络类库,可以实现无痛的网络连接,联网的底层细节被隐藏在Java的本机安装系统里,由JVM进行控制。并且Java实现了一个跨平台的网络库,程序员面对的是一个统一的网络编程环境。
网络通信要素的概述;网络通信有三大要素:IP,端口号,网络通信协议。
IP:网络当中定位的某台主机。
端口号:找到当前主机上哪一个应用程序在进行通信。
网络通信协议:计算机网络中实现通信必须有的一些约定(对速率,传输代码,代码结构,传输控制步骤等制定的标准)。
IP和端口号
1. IP地址:InetAddress
IP:他为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异。在Java中使用 InetAddress 类表示IP。
域名:由于IP地址具有不方便记忆并且不能显示地址组织的名称和性质等缺点,人们设计出了域名,并通过网域名称系统(DNS,Domain Name System)来将域名和IP地址相互映射,使人更方便地访问互联网,而不用去记住能够被机器直接读取的IP地址数串。(如:www.baidu.com)
本地回路地址:127.0.0.1 对应着 Localhost
IP地址分类方式1:IPV4 和 IPV6
- IPV4: 4个字节组成,4个0-255。大概42亿,30亿都在北美,亚洲4亿.2011年初已经用尽,以点分十进制表示,如192.168.01。
- IPV6: 128位(16个字节),写成8个无符号整数,每个整数用四个十六进制位表示,数字间用冒号分开,如3ffe:3201:1401:1280:c8ff:fe4d:db39:1984。
IP地址分类方式2:公网地址(万维网使用)和私有地址(局域网使用)
- 私有地址:以192.168.开头,范围即为192.168.0.0 - 192.168.255.255。专门为组织机构内部使用。
实例化InetAddress的两个方法: getByName(String host),getLocalHost()
以及两个常用方法getHostName()/获取域名,getHostAddress()/获取IP地址
实例化InetAddress的两个方法 getByName(String host),getLocalHost()
@Test
public void myTest(){
try {
InetAddress inet1 = InetAddress.getByName("192.168.10.14");
System.out.println(inet1);//输出192.168.10.14
InetAddress inet2 = InetAddress .getByName("www.atguigu.com");
System.out.println(inet2);//输出www.atguigu.com/58.216.118.229
System.out.println(inet2.getHostAddress());
System.out.println(inet2.getHostName());
InetAddress inet3 = InetAddress.getLocalHost();//获取本机地址
System.out.println(inet3);
} catch (UnknownHostException e) {
} finally {
}
}
2. 端口号
端口号标识正在计算机上运行的进程(程序),不同的进程有不同的端口号(范围:0 - 65535)。
端口分类:
- 公认端口:0-1023.被预先定义的服务通信占用(如:HTTP占用端口80,FTP占用端口21)
- 注册端口:1024 - 49151。分配给用户进程或应用程序。(如Tomcat占用端口8080,MySQL占用端口3306,Oracle占用端口1521)
- 动态/私有端口:49152 - 65535
端口号与IP地址的组合得出一个网络套接字:Socket
网络通讯协议
网络通信协议:计算机网络中实现通信必须有的一些约定(对速率,传输代码,代码结构,传输控制步骤等制定的标准)。
通信协议的分层思想:同层间可以通信,上一层可以调用下一层,而隔层之间不发生关系。
TCP协议:
- 使用TCP协议前,须先建立TCP连接,形成传输数据通道。
- 传输前,采用 ”三次握手“ 的方式,点对点通信,是可靠的。
- TCP协议进行通信的两个进程:客户端,服务端。
- 在连接中可进行大数据量的传输。
- 传输完毕,需要释放已建立的链接(关闭连接时四次挥手,客户端与服务端任意一方都可以主动发起挥手动作,一般情况下都是客户端主动断开连接),效率低。
-
@Test //客户端 public void cliebt(){ Socket socket = null; OutputStream os = null; try { //1. 创建socket对象,指明服务器端的ip和端口号 InetAddress inet = InetAddress.getByName("127.0.0.1"); socket = new Socket(inet,8899); //2. 获取一个输出流, os = socket.getOutputStream(); //3. 写出数据 os.write("你好!我是曹承浩".getBytes()); } catch (IOException e) { e.printStackTrace(); } finally { //4. 资源的关闭 if (os != null) { try { os.close(); } catch (IOException e) { e.printStackTrace(); } } if (socket != null) { try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } } } @Test //服务器端 public void server(){ ServerSocket ss = null; Socket socket = null; InputStream is = null; ByteArrayOutputStream baos = null; try { //1. 创建服务器端的SeverSocket,知名自己的端口号 ss = new ServerSocket(8899); //2. 调用accept()接受来自于客户端的socket socket = ss.accept(); //3. 获取输入流 is = socket.getInputStream(); //4. 读取输入流中的数据 baos = new ByteArrayOutputStream(); byte[] buffer = new byte[5]; int len; while((len = is.read(buffer)) != -1){ baos.write(buffer,0,len); } System.out.println(baos.toString()); } catch (IOException e) { e.printStackTrace(); } finally { //5. 资源关闭 if (baos != null) { try { baos.close(); } catch (IOException e) { e.printStackTrace(); } } if(is != null) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } if(socket != null) { try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } if(ss != null) { try { ss.close(); } catch (IOException e) { e.printStackTrace(); } } } }
UDP协议:
- 将数据,源,目的封装成数据包,不需建立连接。
- 每个数据限制在64k内。
- 发送不管对方是否准备好,接收方收到也不确认,故是不可靠的。
- 可以广播发送。
- 发送到数据结束时无需释放资源,开销小,速度快。
public class UDPtest {
//客户端
@Test
public void sender() throws IOException {
DatagramSocket socket = new DatagramSocket();
String str = "我是UDP方式发送的导弹";
byte[] data = str.getBytes();
InetAddress inet = InetAddress.getLocalHost();
DatagramPacket packet = new DatagramPacket(data,0,data.length,inet,9090);
socket.send(packet);
socket.close();
}
//服务端
@Test
public void receiver() throws IOException {
DatagramSocket socket = new DatagramSocket(9090);
byte[] buffer = new byte[100];
DatagramPacket packet = new DatagramPacket(buffer,0,buffer.length);
socket.receive(packet);
System.out.println(new String(packet.getData(),0,packet.getLength()));
socket.close();
}
}
注意;
- 当使用UDP协议时,如果先启用客户端,后启用服务端,则服务器端将会接受不到数据。在使用TCP协议进行同等操作时,将会报异常。(因为两者原理不同,TCP会先确认服务器端是否在,然后传输数据在一定时间内服务器如果不响应,就会连接不成功。UDP在传输数据时则不会进行该操作,直接将数据扔给对方)
URL网络编程
URL(Uniform Resource Locator)统一资源定位符,他表示Internet上某一资源的地址。
URL的基本结构(5部分构成)
- <传输协议>://<主机名>:<端口号>/<文件名>#片段名?参数列表
| String getProtocol() | 获取该URL协议名 |
| String getHost() | 获取该URL的主机名 |
| String getPort() | 获取URL端口号 |
| String getPath() | 获取该URL的文件路径 |
| String getFile() | 获取该URL的文件名 |
| String getQuery() | 获取该URL的查询名 |
public class urltest {
public static void main(String[] args) {
HttpURLConnection urlConnection = null;
InputStream is = null;
FileOutputStream fos = null;
try {
//指定资源
URL url = new URL("https://image.baidu.com/search/detail?ct=503316480&");
//获取服务器的连接对象
urlConnection = (HttpURLConnection) url.openConnection();
//连接服务器
urlConnection.connect();
//得到一个输入流
is = urlConnection.getInputStream();
//输出资源到指定位置
fos = new FileOutputStream("is A beauty.jpg");
byte[] buffer = new byte[1024];
int len;
while ((len = is.read(buffer) ) != -1){
fos.write(buffer,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//资源关闭
if(is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(urlConnection != null) {
urlConnection.disconnect();
}
}
}
}



