目录
Socket 套接字
Socket套接字,是由系统提供用于网络通信的技术,是基于TCP/IP协议的网络通信的基本操作单元。基于Socket套接字的网络程序开发就是网络编程
网络编程套接字,是操作系统给应用程序提供的一组API(叫做socket API)
socket可以视为应用层和传输层之间的通信桥梁
传输层的核心协议有两种,TCP,UDP
socket API也有对应的两组,分为以下两种:
TCP:有连接;可靠传输;面向字节流;全双工
UDP:无连接;不可靠传输;面向数据报;全双工
有连接:比如打电话,得先接通,才能相互交互数据
无连接:想发微信,不需要接通,直接就能发数据
可靠传输:传输过程中,发送方知道接受方没有收到数据
不可靠传输:传输过程中,发送方不知道接收方有没有收到数据
面向字节流:依字节为单位进行传输(非常类似于文件操作中的字节流)
面向数据报:以数据报为单位进行传输(一个数据报都会明确大小)一次发送/接受必须是一个完整的数据报,不能是半个或者一个半
全双工:一条链路,双向通信
半双工:一条链路,单向通信
UDP数据报套接字编程
1.DatagramSocket API
DatagramSocket API是UDP Socket,用于发送和接受UDP数据报
构造方法
方法签名 | 方法说明 |
---|---|
DatagramSocket() | 创建一个UDP数据报套接字的Socket,绑定到本机任意一个随机端口(一般用于客户端) |
DatagramSocket(int port) | 创建一个UDP数据报套接字的Socket,绑定到本机指定的端口(一般用于服务端) |
方法
方法签名 | 方法说明 |
void receive(DatagramPacket p) |
从此套接字接受数据报(如果没有接受到数据报,该方法会阻塞等待) |
void send(DatagramPacket p) |
从此套接字发送数据报(不会阻塞等待,直接发送) |
void close() | 关闭此数据报套接字 |
2.DatagramPacket API
DatagramPacket
是UDP Socket发送和接收的数据报
构造方法
方法签名 | 方法说明 |
DatagramPacket(byte[] buf, int length) | 构造一个DatagramPacket以用来接收数据报,接收的数据保存在字节数组(第一个参数buf)中,接收指定长度(第二个参数length) |
DatagramPacket(byte[] buf, int offset, int length,SocketAddress address) | 构造一个DatagramPacket以用来发送数据报,发送的数据为字节数组(第一个参数buf)中,从0到指定长度(第二个参数length)。address指定目的主机的IP和端口号 |
方法
方法签名 | 方法说明 |
InetAddress getAddress() | 从接收的数据报中,获取发送端主机IP地址;或从发送的数据报中,获取接收端主机IP地址 |
int getPort() | 从接收的数据报中,获取发送端主机的端口号;或从发送的数据报中,获取接收端主机端口号 |
byte[] getData() | 获取数据报中的数据 |
注:构造UDP发送的数据时,需要传入SocketAddress,该对象可以使用InetSocketAddress来创建。
InetSocketAddress的构造方法 |
|
方法签名 | 方法说明 |
---|---|
InetSocketAddress(InetAddress addr, int port) | 创建一个Socket地址,包含IP地址和端口号 |
3.基本使用方法:
服务端:
1.创建一个DatagramSocket对象,创建的同时关联一个端口号
2.读取请求,并解析
3.根据请求计算响应
4.把响应写回到客户端
5.打印日志
客户端:
1.创建一个DatagramSocket对象,创建的同时指定服务器的ip和端口号
2.读取输入的数据
3.构造请求并发送给服务器
4.从服务器读取响应
5.把数据显示给用户
代码示例:UdeEchoServer
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 来进行填充数据