Java学习笔记——网络编程
网络最主要的作用在于共享设备和传输数据,无论是共享或传输数据,务必需要保证准确地匹配目的主机。
通过IP地址和域名,可以精确地匹配目标主机,是网络中资源共享、数据传输的依据。
- 可以借助主机端口精确地确定客户访问的是这台主机中的哪一个应用程序
- 在一台主机上,应用程序可以占用任何一个端口号;一旦应用程序占据这个端口号,其它应用将不能再占用该端口。
- 在主机中,端口号1~1024是系统保留端口号,用来为常用的网络服务程序所占用。用户自定义应用程序,最好占用其它端口号。
网络基础:TCP/UDP协议
- TCP传输控制协议,是一种面向连接的、可靠的、基于字节流的传输层通信协议。
需要首先在网络两端建立安全连接,再进行数据传递,确保网络双方完整无误地传输数据。 - UDP用户数据报协议,是一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务。
无需建立网络双方连接,直接发送数据包(包含目的地址信息),可能会因为网络问题导致数据传输失败等问题,但是传输速度很快,常用于局域网中传输数据。
网络编程
网络编程是指通过编程方式实现两个(或多个)设备之间的数据传输。
网络编程是基于“请求-响应”模式的:网络中某一端发出请求,另一端接收到请求后,响应请求方的请求。
“请求方”称之为客户端,“响应方”称之为服务器端。
网络编程在客户端和服务器端之间传输数据可以采用TCP方式,也可以采用UDP方式。
网络编程开发模式
- 客户端/服务器端模式(C/S模式):对于不同的服务器端程序建立不同的客户端程序。
- 浏览器/服务器端模式(B/S模式):对于不同的服务器端程序使用统一的“客户端”(即浏览器)即可。
Java网络编程核心类
URL类:统一资源定位符,指向互联网“资源”的指针。
- 常用构造方法:
• URL(String url); // 通过给定字符串建立URL对象
–常用方法:
• InputStream openStream(); // 打开当前URL连接的输入流
• URLConnection openConnection(); // 建立URL网络连接
URLConnection类
应用程序和 URL 之间的通信链接,URLConnection对象可以向所代表的URL发送请求和读取URL的资源
- 对象建立方法:
• 通过URL对象的openConnection() 方法创建
• 使用构造方法:URLConnection( URL url); //不建议使用 - 常用方法:
• 获得响应消息头类方法:getContentType()类型、getContentLength()长度、getContentEncoding()编码方式、……
• 获得响应消息主体:getContent()
• 获得当前连接输入/输出流对象:getInputStream()、getOutputStream()
HttpURLConnection类
特定支持HTTP协议的URLConnection。
- 对象建立方法:
• 通过URL对象的openConnection()方法创建,强制转换为目标对象
• 使用构造方法:HttpURLConnection( URLConnection url);
HttpURLConnection hc = (HttpURLConnection) conn;
- 常用方法:
• 从URLConnection类继承的方法
• 针对HTTP请求响应消息的特定方法:getRequestMethod()、setRequestMetho()、getResponseCode()、getResponseMessage()、……
Socket网络编程
客户端和服务器端建立连接后,连接两端将会建立一个虚拟“线缆”,在网络编程中称之为Socket(套接字);其后在网络两端传输数据都是通过Socket进行的。
– Socket借助IP地址和端口号,对应某一台主机中的某一个应用程序。
– Socket的主要作用是维护网络连接、在网络双方传输数据。
Socket类
客户端套接字类。实现客户端向服务器发送数据、接收服务器数据等功能;实现服务器端向客户端发送数据、接收客户端数据等功能。
- 构造方法:
• Socket(InetAddress address, int port); //不常用
• Socket(String host, int port); //常用 指定IP地址和端口号找到程序 - 常用方法:
• getInputStream(); // 获得网络输入流
• getOutputStream(); // 获得网络输出流
• close(); // 关闭Socket连接
客户端Socket应用程序所做的工作主要有:
- 与服务器端建立连接(通过IP和端口号确定主机上的程序)。
Socket client = new Socket(“localhost”, 80); - 向服务器端发送数据,接收服务器端数据。
• 向服务器端发送数据:os = client.getOutputStream();
• 接收服务器端数据:is = client.getInputStream(); - 关闭Socket连接。
client.close();
ServerSocket类
服务器端套接字类。监听服务器指定端口,接收客户端连接请求。
- 构造方法:
ServerSocket(int port); - 常用方法:
• accept(); // 用于产生“阻塞”,直到接收一个连接,返回客户端Socket对象
• close(); // 关闭服务器端Socket监听
服务器端所做的主要工作有:
- 监听特定端口。
ServerSocket server = new ServerSocket(8888);
与客户端的端口相同 - 接收客户端连接。
Socket client = server.accept(); - 接收客户端请求,向客户端发送响应。
• 接收客户端请求数据:is = client.getInputStream();
• 向客户端响应数据:os = client.getOutputStream(); - 关闭连接。
关闭客户端:client.close();
关闭服务器端:server.close();
UDP网络编程
一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务。
UDP网络编程必须提供以下对象来完成不同的任务:
- 网络两端接收消息或发送消息的对象(监听本机端口、发送消息、接收消息)。
- 数据包对象(包含目的地IP和端口信息、数据报文信息)。
DatagramSocket类
客户端/服务器端网络Socket端口对象。
- 构造方法:
• DatagramSocket(); // 创建一个空的Socket对象
•DatagramSocket(int port); //创建指定监听端口的Socket对象
这个端口并不是目标的端口,是监测本机是否有数据进入的端口 - 常用方法:
• void send(DatagramPacket p); // 发送数据报文
• void receive(DatagramPacket p); // 接收数据报文
DatagramPacket类
数据报文对象。
- 构造方法:
• DatagramPacket(byte[] buf, int len); // 用空数组创建对象,用来接收数据。
• DatagramPacket(byte[] buf, int offset, int len); // 接收数据的特定部分。
• DatagramPacket(byte[] buf, int len, InetAddress addr, int port); // 包含数据的数组创建对象,用来发送数据,同时指明数据目的地和目标端口号。
• DatagramPacket(byte[] buf, int offset, int len, InetAddress addr, int port); // 发送数据的指定部分。 - 客户端程序:
–基本工作流程:
• 创建DatagramSocket对象
• 封装请求数据,创建DatagramPacket对象
• 发送请求
// 创建DatagramSocket对象
DatagramSocket client = new DatagramSocket();
// 准备请求数据
byte[] buf = “客户端请求数据".getBytes();
InetAddress address = InetAddress.getLocalHost();
// 创建DatagramPacket对象
DatagramPacket request =
new DatagramPacket(buf, buf.length, address , 8888);
// 发送请求
client.send(request);
- 服务器程序:
–基本工作流程:
• 创建DatagramSocket对象,监听特定端口
• 创建DatagramPacket对象(空缓冲区)
• 接收客户端请求
• 封装服务器响应数据,创建DatagramPacket对象
• 发送服务器响应给指定客户端
// 创建DatagramSocket对象,监听特定端口
DatagramSocket server = new DatagramSocket(8888);
// 准备空缓冲区
byte[] buf = new byte[1024];
// 循环等待客户端请求
while (true) {
// 创建DatagramPacket对象
DatagramPacket request = new DatagramPacket(buf, buf.length);
// 接收客户端请求
server.receive(request);
// 准备服务器端响应数据包
byte[] resBuf = "from server: ".getBytes();
DatagramPacket response = new DatagramPacket(
resBuf, resBuf.length, request.getAddress(), request.getPort());
// 发送服务器响应
server.send(response);
}