コンテンツにスキップ

UDP ソケット

QUIC は UDP の上で動きます。 wired は libc を介さず、カーネルと直接やり取りします。 このページでは 127.0.0.1 に 2 つのソケットをバインドし、一方からもう一方へ hello を送ります。

コード

main.c
#define WIRED_MAIN
#include "wired.h"
int wired_main(int argc, char** argv) {
(void)argc;
(void)argv;
static const u8 lo[4] = {127, 0, 0, 1};
sockaddr a, b, from;
wired_udp_addr(&a, 14512, lo);
wired_udp_addr(&b, 14513, lo);
i64 sa = wired_udp_socket();
i64 sb = wired_udp_socket();
if (wired_udp_bind(sa, &a) < 0 || wired_udp_bind(sb, &b) < 0) return 1;
/* a -> b, then b reads it along with the sender's address. */
wired_udp_send(sa, &b, wired_span_cstr("hello"));
u8 buf[64];
i64 n = wired_udp_recvfrom(sb, wired_mspan_of(buf, sizeof buf - 1), &from);
if (n < 0) return 1;
buf[n] = 0;
u16 port =
(u16)((from.port_be >> 8) | (from.port_be << 8)); /* to host order */
wired_dprintf(
2, "recv %llu bytes: %s from %llu\n", (u64)n, (const char*)buf,
(u64)port);
wired_udp_close(sa);
wired_udp_close(sb);
return 0;
}

実行結果

Terminal window
$ ./quic-udp
recv 5 bytes: hello from 14512
  • wired_udp_addr(&sa, port, octets) はアドレスを作ります。 どのソケットも IPv4 と IPv6 の両方を扱うデュアルスタックなので、IPv4 のオクテットは IPv4 射影 IPv6 アドレス(IPv6 の形式で表した IPv4 アドレス)になります。
  • wired_udp_socket はソケットを開き、wired_udp_bind はそれをバインドします。 どちらも失敗すると負の errno(エラー番号を負にした値)を返します。
  • wired_udp_send(fd, &dst, span) はデータグラムを 1 つ送ります。 wired_udp_recvfrom(fd, buf, &src) はデータグラムを 1 つ受け取り、送信元のアドレスを書き込みます。
  • sockaddr.port_be はネットワークバイトオーダー(上位バイトが先に並ぶ順序)なので、表示する前にバイト順を入れ替えます。
  • wired_udp_close はソケットを解放します。