Java 网络编程概览
前言:
手写 HTTP 服务器需要使用到 ServerSocket 来绑定一个端口,监听客户端的请求,这是 Java 网络编程提供的能力。
相关的源码在 java.net 包中,它们提供了低层次的通信细节,可以直接使用这些类和接口来专注于业务逻辑,而不用关注通信细节。
java.net 包提供了两种常见的网络协议支持:
- TCP : TCP 是传输控制协议的缩写,保障了两个应用程序之间的可靠通信。
- UDP: UDP 是用户数据协议的缩写,它是一个无连接的协议
Socket 与 ServerSocket
Socket 底层是 TCP 协议,提供了两台计算机之间的通信机制,客户端程序创建一个 Socket,并尝试连接服务器的 Socket。
java.net.Socket
---> Java 对客户端 Socket
的实现java.net.ServerSocket
---> Java 对**服务端 Socket
** 的实现
客户端与服务端直接可以建立连接,然后进行通信。
下面是 Socket 通信中建立连接的基本流程:
- 1、服务器实例化一个 ServerSocket 对象,并且绑定一个具体的端口来接收请求
- 2、 服务器调用 ServerSocket 的 accept 方法,该方法一直等待,直到客户端连接到服务器的监听端口
- 3、 服务器监听端口时,客户端实例化一个 Socket 对象,指定服务器的名称与端口号进行连接。
- 4、 服务器端,accept 方法返回服务器上一个新的 Socket 引用,该引用连接到客户端的 Socket 上。
连接建立后,可以通过使用 I/O 流进行通信,每个 Socket 都有一个 输出流和一个输入流。
客户端的输出流连接到服务端的输入流,客户端的输入流连接到服务端的输出流。
TCP
是一个 双向通信协议
,因此数据可以通过两个数据流在同一时间发送。
ServerSocket
Java 中提供服务器端套接字功能的类。通过它可以让主机监听某个端口,接收其他端的请求,并且处理完后可以对其他端做出响应。
但是真正处理请求的是 SocketImpl
类,它提供了一个创建 SocketImpl
实例的工厂,使用了工厂模式。
默认实现类是 SockesSocketImpl
, ServerSocket
和 Socket
只是一个门面模式。
创建 ServerSocket
构造函数 | 描述 |
---|---|
ServerSocket() | 创建非绑定服务器套接字。 |
ServerSocket(int port) | 创建绑定到 特定端口 的服务器套接字。 |
ServerSocket(int port, int backlog) | 利用指定的 backlog 创建服务器套接字并将其绑定到指定的本地端口号。 |
ServerSocket(int port, int backlog, InetAddress address) | 使用指定的端口、监听 backlog 和要绑定到的本地 IP 地址创建服务器。 |
Socket 通信示例:
创建一个 ServerSocket,并打印 HTTP 请求的具体内容:
public class Server01 {
public static void main(String[] args) {
Server01 server = new Server01();
server.start();
}
private ServerSocket serverSocket;
public void start() {
// 初始化 serversocket 实例
try {
serverSocket = new ServerSocket(8888);
// 接收浏览器请求与
receive();
} catch (IOException e) {
e.printStackTrace();
System.out.println("服务启动失败");
}
}
public void receive() {
try {
Socket client = serverSocket.accept();
System.out.println("一个客户端与服务器建立了连接");
// 通过输入流获取请求协议
InputStream is = client.getInputStream();
// 一次性读取全部请求相关信息
byte[] data = new byte[1024 * 1024];
int len = is.read(data);
String requestInfo = new String(data, 0, len);
System.out.println("请求内容:"+requestInfo);
} catch (IOException e) {
e.printStackTrace();
System.out.println("客户端建立连接错误");
}
}
public void stop() {
}
}
这里使用浏览器访问接口 8888
,可以看到虽然没有返回给客户端数据,但是我的服务端已经接收到了 客户端的 Socket 请求,并打印了对应的数据。
Q.E.D.
Comments | 0 条评论