socket API
网络编程套接字是操作系统给应用程序提供的一组API(叫做socket API)
socket可以视为应用层和传输层之间的通信桥梁
socket API也有对应的两组
由于上一节课(网络编程1)我们看到TCP和UDP差别很大,因此API差别也很大
下面我们来讲一下UDP socket和TCP socket
先讲UDP socket
UDP socket中主要涉及两个类:
1.DatagramSocket
一个DatagramSocket对象就对应到操作系统中的一个socket文件
socket文件就对应着"网卡"这种硬件设备.从socket文件读数据,本质上就是读网卡,从socket文件写数据,本质上就是写网卡.socket就像一个遥控器,它可以操作网卡.
2.DatagramPacket
DatagramPacket代表了一个UDP数据报,他是使用UDP传输数据的基本单位,每次发送/接收数据都是在传输一个DatagramPacket对象
下面我们来写一下最简单的
UDP的客户端服务器程序---回显服务(请求内容是什么,得到的响应就是什么)
回显服务器:UdpEchoServer
package network;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
// 站在服务器的角度:
// 1. 源 IP: 服务器程序本机的 IP
// 2. 源端口: 服务器绑定的端口 (此处手动指定了 9090)
// 3. 目的 IP: 包含在收到的数据报中. (客户端的IP)
// 4. 目的端口: 包含在收到的数据报中. (客户端的端口)
// 5. 协议类型: UDP
public class UdpEchoServer {
// 进行网络编程, 第一步就需要先准备好 socket 实例~ 这是进行网络编程的大前提.
private DatagramSocket socket = null;
public UdpEchoServer(int port) throws SocketException {
socket = new DatagramSocket(port);
}
// 启动服务器.
public void start() throws IOException {
System.out.println("启动服务器!");
// UDP 不需要建立连接, 直接接收从客户端来的数据即可
while (true) {
// 1. 读取客户端发来的请求
DatagramPacket requestPacket = new DatagramPacket(new byte[1024], 1024);
socket.receive(requestPacket); // 为了接受数据, 需要先准备好一个空的 DatagramPacket 对象, 由 receive 来进行填充数据
// 把 DatagramPacket 解析成一个 String
String request = new String(requestPacket.getData(), 0, requestPacket.getLength(), "UTF-8");
// 2. 根据请求计算响应(由于咱们这是一个回显服务, 2 省略)
String response = process(request);
// 3. 把响应写回到客户端
DatagramPacket responsePacket = new DatagramPacket(response.getBytes(), response.getBytes().length,
requestPacket.getSocketAddress());
socket.send(responsePacket);
System.out.printf("[%s:%d] req: %s, resp: %s\n",
requestPacket.getAddress().toString(), requestPacket.getPort(), request, response);
}
}
// 由于是回显服务, 响应就和请求一样了.
// 实际上对于一个真实的服务器来说, 这个过程是最复杂的. 为了实现这个过程, 可能需要几万行, 几十万行代码....
public String process(String request) {
return request;
}
public static void main(String[] args) throws IOException {
UdpEchoServer server = new UdpEchoServer(9090);
server.start();
}
}
下面是对代码的一些解释:
多个进程不能绑定同一个端口,但一个进程可以绑定多个端口---->我们就把端口想象成手机号,几个人不能共用一个手机号,但是一个人可以有多个手机号
如果一个程序需要使用网络通信,那么至少需要一个端口号(就像一个人要想,他至少需要一个手机号码)
回显客户端:UdpEchoClient
package network;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.Sock