[Dev] 同じポートをIPv4とIPv6で待ち受けする。
検証内容
- 同じポートをIPv4とIPv6で待ち受けする。
どちらも同じポート3000番でプログラムを起動。(別々のプロセス) - bun/nodejs/goでそれぞれ実行する。
➡️bun失敗。IPv6(だけではなく)とIPv4を一緒にオープンしているため。
➡️nodejs失敗。IPv6(だけではなく)とIPv4を一緒にオープンしているため。
➡️go成功。(TCP4、TCP6を指定してオープン)
bun
cat server1.ts
import { serve } from "bun";
// 第1引数: hostname
// 第2引数: port
const hostname = Bun.argv[2] || "::";
const port = Number(Bun.argv[3] || 3000);
console.log(`listen: [${hostname}]:${port}`);
serve({
hostname,
port,
fetch: async (req) => {
const url = new URL(req.url);
console.log("url.pathname:", url.pathname);
if (url.pathname === "/hivemind/") {
const body = JSON.stringify({
jsonrpc: "2.0",
id: 0,
method: "hive.db_head_state",
params: {}
});
const backend = await fetch("http://localhost:8888", {
//const backend = await fetch("http://113.144.132.118:8888", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Host": "steememory.com",
},
body,
});
const data = await backend.text();
return new Response(data, {
status: backend.status,
headers: {
"Content-Type": "application/json",
},
});
}
return new Response("Not Found", { status: 404 });
},
});
🪣IPv6で待ち受ける
失敗する。IPv6(だけではなく)とIPv4を一緒にオープンしているため。😭

📌0.0.0.0でオープンした場合
tcp4のみオープン。

📌::でオープンした場合
tcp4とtcp6の両方をオープン。🤔

nodejs
cat server1.js
import http from "http";
// 第1引数: hostname
// 第2引数: port
const hostname = process.argv[2] || "::";
const port = Number(process.argv[3] || 3000);
console.log(`listen: [${hostname}]:${port}`);
const server = http.createServer(async (req, res) => {
const url = new URL(req.url, `http://${req.headers.host}`);
console.log("url.pathname:", url.pathname);
if (url.pathname === "/hivemind/") {
const body = JSON.stringify({
jsonrpc: "2.0",
id: 0,
method: "hive.db_head_state",
params: {}
});
try {
const backendRes = await fetch("http://localhost:8888", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Host": "steememory.com",
},
body,
});
const data = await backendRes.text();
res.writeHead(backendRes.status, {
"Content-Type": "application/json",
});
res.end(data);
return;
} catch (err) {
res.writeHead(500, {
"Content-Type": "application/json",
});
res.end(JSON.stringify({ error: String(err) }));
return;
}
}
res.writeHead(404, {
"Content-Type": "text/plain",
});
res.end("Not Found");
});
// listen
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
🪣IIPv6で待ち受ける
失敗する。IPv6(だけではなく)とIPv4を一緒にオープンしているため。😭

GO
cat server1.go
package main
import (
"bytes"
"io/ioutil"
"log"
"net"
"net/http"
"os"
)
func main() {
hostname := "::"
port := "3000"
if len(os.Args) > 1 {
hostname = os.Args[1]
}
if len(os.Args) > 2 {
port = os.Args[2]
}
addr := net.JoinHostPort(hostname, port)
log.Printf("listen: [%s]:%s", hostname, port)
mux := http.NewServeMux()
mux.HandleFunc("/hivemind/", func(w http.ResponseWriter, r *http.Request) {
log.Println("url.pathname:", r.URL.Path)
body := []byte(`{
"jsonrpc": "2.0",
"id": 0,
"method": "hive.db_head_state",
"params": {}
}`)
req, err := http.NewRequest("POST", "http://localhost:8888", bytes.NewBuffer(body))
if err != nil {
http.Error(w, err.Error(), 500)
return
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Host", "steememory.com")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
http.Error(w, err.Error(), 500)
return
}
defer resp.Body.Close()
respBody, _ := ioutil.ReadAll(resp.Body)
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(resp.StatusCode)
w.Write(respBody)
})
server := &http.Server{
Handler: mux,
}
ip := net.ParseIP(hostname)
network := "tcp6"
if ip != nil && ip.To4() != nil {
network = "tcp4"
}
// ln, err := net.Listen("tcp", addr)
log.Printf("addr: %s %s %s", hostname, network, addr)
ln, err := net.Listen(network, addr)
if err != nil {
log.Fatal(err)
}
log.Fatal(server.Serve(ln))
}





