Working with Network Programming
1. Using HttpClient API
| Builder Option | Use |
|---|---|
version(HTTP_2) | HTTP/2 default |
followRedirects(NORMAL) | Auto-follow |
connectTimeout(d) | TCP connect |
executor(exec) | Async pool |
cookieHandler(h) | Cookie store |
authenticator(a) | Basic/Digest |
proxy(ProxySelector) | Proxy |
2. Sending HTTP Requests
| Method | Body Publisher |
|---|---|
| GET | BodyPublishers.noBody() |
| POST | BodyPublishers.ofString(json) |
| File | BodyPublishers.ofFile(path) |
| Bytes | BodyPublishers.ofByteArray(b) |
| Reactive | BodyPublishers.fromPublisher(...) |
Example: POST JSON
HttpClient client = HttpClient.newHttpClient();
HttpRequest req = HttpRequest.newBuilder(URI.create("https://api.example.com/users"))
.header("Content-Type", "application/json")
.POST(BodyPublishers.ofString(json))
.build();
HttpResponse<String> res = client.send(req, BodyHandlers.ofString());
3. Handling HTTP Responses
| BodyHandler | Result |
|---|---|
ofString() | String |
ofByteArray() | byte[] |
ofFile(path) | Path |
ofLines() | Stream<String> |
discarding() | Drop body |
4. Using Async HTTP Requests
Example: Async with chain
client.sendAsync(req, BodyHandlers.ofString())
.thenApply(HttpResponse::body)
.thenAccept(System.out::println);
| API | Returns |
|---|---|
sendAsync(req, handler) | CompletableFuture<HttpResponse> |
sendAsync(req, h, pushHandler) | HTTP/2 push |
5. Configuring HttpClient (timeouts, redirects, authenticators)
| Setting | API |
|---|---|
| Request timeout | HttpRequest.newBuilder().timeout(d) |
| Connect timeout | Client builder |
| Redirects | NEVER / NORMAL / ALWAYS |
| SSL | sslContext(ctx) |
6. Working with WebSocket
| API | Use |
|---|---|
HttpClient.newWebSocketBuilder().buildAsync(uri, listener) | Connect |
WebSocket.Listener | onOpen/onText/onBinary/onClose |
sendText / sendBinary / sendPing | Send |
request(n) | Backpressure |
7. Using ServerSocket and Socket
| Class | Use |
|---|---|
ServerSocket(port) | Listen |
accept() | Block for client |
Socket(host, port) | Connect |
getInputStream / getOutputStream | I/O |
8. Using DatagramSocket
| API | Use |
|---|---|
DatagramSocket(port) | UDP socket |
send(DatagramPacket) | Send packet |
receive(DatagramPacket) | Block for inbound |
MulticastSocket | Multicast (use ND for IPv6) |
9. Configuring Socket Options
| Option | Effect |
|---|---|
| SO_TIMEOUT | Read timeout |
| SO_KEEPALIVE | TCP keepalives |
| TCP_NODELAY | Disable Nagle |
| SO_REUSEADDR | Bind reuse |
| SO_LINGER | Close behavior |
| SO_RCVBUF / SO_SNDBUF | Buffer sizes |
10. Using NIO Channels
| Channel | Use |
|---|---|
| SocketChannel | Non-blocking TCP |
| ServerSocketChannel | Non-blocking listener |
| DatagramChannel | UDP |
| FileChannel | File I/O + transferTo (zero-copy) |
| Pipe | In-process channels |
11. Understanding Selectors
| API | Use |
|---|---|
Selector.open() | Create |
channel.register(sel, ops) | Register interest |
select() / select(t) / selectNow() | Block / timed / poll |
| Ops | OP_READ, OP_WRITE, OP_ACCEPT, OP_CONNECT |
12. Implementing Non-Blocking Server
Example: Selector loop
Selector sel = Selector.open();
ServerSocketChannel ssc = ServerSocketChannel.open();
ssc.bind(new InetSocketAddress(8080)).configureBlocking(false);
ssc.register(sel, SelectionKey.OP_ACCEPT);
while (sel.select() > 0) {
for (var key : sel.selectedKeys()) {
if (key.isAcceptable()) accept(key);
else if (key.isReadable()) read(key);
}
sel.selectedKeys().clear();
}
| Pattern | Detail |
|---|---|
| Reactor | Single thread, multiplex |
| Modern alt | Virtual threads + blocking I/O |