mirror of
https://github.com/yhirose/cpp-httplib.git
synced 2026-09-30 20:52:31 +07:00
Update documentation
This commit is contained in:
@@ -347,6 +347,25 @@ int port = svr.bind_to_any_port("0.0.0.0");
|
||||
svr.listen_after_bind();
|
||||
```
|
||||
|
||||
### Port sharing and exclusive binding
|
||||
|
||||
By default, the server socket enables address/port reuse: `SO_REUSEPORT` where it is available (Linux, macOS), and `SO_REUSEADDR` otherwise (Windows). A restarted server can bind again immediately, but binding to a port that another server is already listening on also succeeds, and connections are distributed between them.
|
||||
|
||||
If you want `listen()` to fail when the port is already in use, replace the default socket options with `set_socket_options`:
|
||||
|
||||
```cpp
|
||||
svr.set_socket_options([](socket_t sock) {
|
||||
#ifdef _WIN32
|
||||
httplib::set_socket_opt(sock, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, 1);
|
||||
#else
|
||||
httplib::set_socket_opt(sock, SOL_SOCKET, SO_REUSEADDR, 1);
|
||||
#endif
|
||||
});
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> Setting only `SO_REUSEADDR` is not enough on Windows. There, `SO_REUSEADDR` allows two sockets that both set it to bind to the same port, so use `SO_EXCLUSIVEADDRUSE` instead.
|
||||
|
||||
### Static File Server
|
||||
|
||||
```cpp
|
||||
|
||||
@@ -43,15 +43,40 @@ svr.listen_after_bind();
|
||||
|
||||
## Check the return values
|
||||
|
||||
`bind_to_port()` returns `false` on failure — typically when the port is already taken. Always check it.
|
||||
`bind_to_port()` returns `false` on failure, for example when you don't have permission to bind to the port. Always check it.
|
||||
|
||||
```cpp
|
||||
if (!svr.bind_to_port("0.0.0.0", 8080)) {
|
||||
std::cerr << "port already in use" << std::endl;
|
||||
std::cerr << "bind failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
```
|
||||
|
||||
`listen_after_bind()` blocks until the server stops and returns `true` on a clean shutdown.
|
||||
|
||||
## Detect a port that's already in use
|
||||
|
||||
With the default settings, you can actually bind to a port another server is already using. That's because cpp-httplib sets `SO_REUSEPORT` (Linux, macOS) or `SO_REUSEADDR` (Windows) on the server socket. A restarted server can bind again right away. The flip side is that a second server on the same port starts without an error, and connections get split between the two.
|
||||
|
||||
To make `bind_to_port()` fail on a port in use, replace the socket options with `set_socket_options()`.
|
||||
|
||||
```cpp
|
||||
svr.set_socket_options([](socket_t sock) {
|
||||
#ifdef _WIN32
|
||||
httplib::set_socket_opt(sock, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, 1);
|
||||
#else
|
||||
httplib::set_socket_opt(sock, SOL_SOCKET, SO_REUSEADDR, 1);
|
||||
#endif
|
||||
});
|
||||
|
||||
if (!svr.bind_to_port("0.0.0.0", 8080)) {
|
||||
std::cerr << "port already in use" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
```
|
||||
|
||||
`set_socket_options()` replaces the defaults entirely. Setting `SO_REUSEADDR` on Linux and macOS keeps the "restarted server can bind again right away" behavior.
|
||||
|
||||
> **Note:** `SO_REUSEADDR` alone isn't enough on Windows. Two sockets that both set it can bind to the same port, so use `SO_EXCLUSIVEADDRUSE` instead.
|
||||
|
||||
> **Note:** To auto-pick a free port, see [S17. Bind to any available port](../s17-bind-any-port). Under the hood, that's just `bind_to_any_port()` + `listen_after_bind()`.
|
||||
|
||||
@@ -43,15 +43,40 @@ svr.listen_after_bind();
|
||||
|
||||
## 戻り値のチェック
|
||||
|
||||
`bind_to_port()`は失敗すると`false`を返します。ポートが既に使われている場合などです。必ずチェックしてください。
|
||||
`bind_to_port()`は失敗すると`false`を返します。ポートにbindする権限が無い場合などです。必ずチェックしてください。
|
||||
|
||||
```cpp
|
||||
if (!svr.bind_to_port("0.0.0.0", 8080)) {
|
||||
std::cerr << "port already in use" << std::endl;
|
||||
std::cerr << "bind failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
```
|
||||
|
||||
`listen_after_bind()`はサーバーが停止するまでブロックし、正常終了なら`true`を返します。
|
||||
|
||||
## 使用中のポートを検出する
|
||||
|
||||
実は、デフォルトの設定では、ほかのサーバーが使っているポートにもbindできてしまいます。cpp-httplibがサーバーソケットに`SO_REUSEPORT`(Linux、macOS)か`SO_REUSEADDR`(Windows)を設定しているからです。再起動したサーバーはすぐにbindし直せます。その代わり、同じポートで2つ目のサーバーを起動してもエラーにならず、接続が両方に振り分けられます。
|
||||
|
||||
使用中のポートで`bind_to_port()`を失敗させたいときは、`set_socket_options()`でソケットオプションを差し替えてください。
|
||||
|
||||
```cpp
|
||||
svr.set_socket_options([](socket_t sock) {
|
||||
#ifdef _WIN32
|
||||
httplib::set_socket_opt(sock, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, 1);
|
||||
#else
|
||||
httplib::set_socket_opt(sock, SOL_SOCKET, SO_REUSEADDR, 1);
|
||||
#endif
|
||||
});
|
||||
|
||||
if (!svr.bind_to_port("0.0.0.0", 8080)) {
|
||||
std::cerr << "port already in use" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
```
|
||||
|
||||
`set_socket_options()`はデフォルトの設定を丸ごと置き換えます。Linux、macOSで`SO_REUSEADDR`を設定しているのは、再起動したサーバーがすぐにbindし直せるようにするためです。
|
||||
|
||||
> **Note:** Windowsでは`SO_REUSEADDR`だけでは足りません。お互いに`SO_REUSEADDR`を設定したソケット同士は、同じポートにbindできてしまいます。`SO_EXCLUSIVEADDRUSE`を使ってください。
|
||||
|
||||
> **Note:** 空いているポートを自動で選びたいときは[S17. ポートを動的に割り当てる](../s17-bind-any-port)を参照してください。こちらも内部では`bind_to_any_port()` + `listen_after_bind()`の組み合わせです。
|
||||
|
||||
Reference in New Issue
Block a user