# 機能設計書: System.Net.Sockets（ソケット通信）

## 1. 機能概要

### 1.1 機能名
System.Net.Sockets（ソケット通信）

### 1.2 機能ID
FUNC-015

### 1.3 機能説明
.NET ランタイムにおける低レベルネットワーク通信機能を提供するライブラリ。Berkeley ソケットインターフェースの.NET実装として、TCP/UDP/RAWソケット通信、IPv4/IPv6サポート、Unix Domain Socket、非同期I/O操作など、OSのネットワークスタック機能へのアクセスを提供する。

### 1.4 関連画面
- なし（基盤ライブラリのため直接的な関連画面は存在しない）

## 2. 機能要件

### 2.1 入力仕様

| 項目名 | データ型 | 必須 | 説明 |
|--------|----------|------|------|
| addressFamily | AddressFamily | Yes | アドレスファミリー（IPv4, IPv6等） |
| socketType | SocketType | Yes | ソケットタイプ（Stream, Dgram等） |
| protocolType | ProtocolType | Yes | プロトコル（TCP, UDP等） |
| localEndPoint | EndPoint | No | ローカルエンドポイント |
| remoteEndPoint | EndPoint | Yes | リモートエンドポイント |
| buffer | byte[]/Memory<byte> | Yes | 送受信バッファ |

### 2.2 出力仕様

| 項目名 | データ型 | 説明 |
|--------|----------|------|
| int | int | 送受信バイト数 |
| Socket | Socket | Accept で受け入れた新規ソケット |
| bool | bool | Connect 結果（非同期完了） |
| EndPoint | EndPoint | 接続先/送信元エンドポイント |

### 2.3 処理フロー（TCPサーバー）

```
Socket(AddressFamily, SocketType, ProtocolType)
    │
    ▼
Bind(localEndPoint)
    │
    ▼
Listen(backlog)
    │
    ▼
┌─────────────────────┐
│ AcceptAsync()       │←─────┐
│ 接続待ち            │      │
└─────────────────────┘      │
    │                        │
    ▼                        │
┌─────────────────────┐      │
│ 新規接続ソケット取得  │      │
│ クライアント処理開始  │      │
└─────────────────────┘      │
    │                        │
    ├── ReceiveAsync()       │
    ├── SendAsync()          │
    └── 処理完了 ─────────────┘
           │
           ▼
       Dispose()
```

## 3. 詳細設計

### 3.1 クラス構成

#### 3.1.1 主要クラス

| クラス名 | 責務 |
|----------|------|
| Socket | ソケット通信の主要クラス |
| TcpClient | TCP クライアント接続のラッパー |
| TcpListener | TCP サーバーリスナーのラッパー |
| UdpClient | UDP 通信のラッパー |
| NetworkStream | Socket の Stream ラッパー |
| SafeSocketHandle | ソケットハンドルの安全なラッパー |

### 3.2 Socket クラス（Socket.cs）

#### 3.2.1 コンストラクタ

```csharp
// シンプルなコンストラクタ（Socket.cs: 72-79行目）
public Socket(SocketType socketType, ProtocolType protocolType)
    : this(OSSupportsIPv6 ? AddressFamily.InterNetworkV6 : AddressFamily.InterNetwork,
           socketType, protocolType)
{
    if (OSSupportsIPv6DualMode)
    {
        DualMode = true;
    }
}

// 完全なコンストラクタ（Socket.cs: 82-100行目）
public Socket(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType)
{
    SocketError errorCode = SocketPal.CreateSocket(addressFamily, socketType, protocolType, out _handle);
    if (errorCode != SocketError.Success)
    {
        throw new SocketException((int)errorCode);
    }
    _addressFamily = addressFamily;
    _socketType = socketType;
    _protocolType = protocolType;
}

// 既存ハンドルからの作成（Socket.cs: 114-117行目）
public Socket(SafeSocketHandle handle)
```

#### 3.2.2 主要プロパティ

| プロパティ | 型 | 説明 |
|------------|------|------|
| AddressFamily | AddressFamily | アドレスファミリー |
| SocketType | SocketType | ソケットタイプ |
| ProtocolType | ProtocolType | プロトコルタイプ |
| LocalEndPoint | EndPoint | ローカルエンドポイント |
| RemoteEndPoint | EndPoint | リモートエンドポイント |
| Connected | bool | 接続状態 |
| Available | int | 受信可能バイト数 |
| Blocking | bool | ブロッキングモード |
| Handle | SafeSocketHandle | ソケットハンドル |
| DualMode | bool | デュアルスタックモード |

#### 3.2.3 静的プロパティ

```csharp
// Socket.cs: 260-266行目
public static bool OSSupportsIPv4 => SocketProtocolSupportPal.OSSupportsIPv4;
public static bool OSSupportsIPv6 => SocketProtocolSupportPal.OSSupportsIPv6;
public static bool OSSupportsUnixDomainSockets => SocketProtocolSupportPal.OSSupportsUnixDomainSockets;
```

### 3.3 主要メソッド

#### 3.3.1 接続関連

```csharp
// サーバー側
public void Bind(EndPoint localEP);
public void Listen(int backlog);
public Socket Accept();
public Task<Socket> AcceptAsync();
public ValueTask<Socket> AcceptAsync(CancellationToken cancellationToken);

// クライアント側
public void Connect(EndPoint remoteEP);
public void Connect(IPAddress address, int port);
public void Connect(string host, int port);
public Task ConnectAsync(EndPoint remoteEP);
public ValueTask ConnectAsync(EndPoint remoteEP, CancellationToken cancellationToken);
```

#### 3.3.2 データ送受信

```csharp
// 同期送信
public int Send(byte[] buffer);
public int Send(byte[] buffer, int offset, int size, SocketFlags socketFlags);
public int Send(ReadOnlySpan<byte> buffer, SocketFlags socketFlags = SocketFlags.None);

// 非同期送信
public Task<int> SendAsync(ArraySegment<byte> buffer, SocketFlags socketFlags);
public ValueTask<int> SendAsync(ReadOnlyMemory<byte> buffer,
    SocketFlags socketFlags = SocketFlags.None,
    CancellationToken cancellationToken = default);

// 同期受信
public int Receive(byte[] buffer);
public int Receive(byte[] buffer, int offset, int size, SocketFlags socketFlags);
public int Receive(Span<byte> buffer, SocketFlags socketFlags = SocketFlags.None);

// 非同期受信
public Task<int> ReceiveAsync(ArraySegment<byte> buffer, SocketFlags socketFlags);
public ValueTask<int> ReceiveAsync(Memory<byte> buffer,
    SocketFlags socketFlags = SocketFlags.None,
    CancellationToken cancellationToken = default);
```

#### 3.3.3 UDP 送受信

```csharp
public int SendTo(byte[] buffer, EndPoint remoteEP);
public int ReceiveFrom(byte[] buffer, ref EndPoint remoteEP);
public Task<int> SendToAsync(ArraySegment<byte> buffer, SocketFlags socketFlags, EndPoint remoteEP);
public Task<SocketReceiveFromResult> ReceiveFromAsync(ArraySegment<byte> buffer,
    SocketFlags socketFlags, EndPoint remoteEP);
```

### 3.4 AddressFamily 列挙型

| 値 | 説明 |
|-----|------|
| InterNetwork | IPv4 |
| InterNetworkV6 | IPv6 |
| Unix | Unix Domain Socket |
| Unspecified | 未指定 |

### 3.5 SocketType 列挙型

| 値 | 説明 |
|-----|------|
| Stream | ストリームソケット（TCP） |
| Dgram | データグラムソケット（UDP） |
| Raw | RAW ソケット |
| Seqpacket | シーケンスパケット |

### 3.6 ProtocolType 列挙型

| 値 | 説明 |
|-----|------|
| Tcp | TCP プロトコル |
| Udp | UDP プロトコル |
| Icmp | ICMP プロトコル |
| IcmpV6 | ICMPv6 プロトコル |
| Raw | RAW IP |

### 3.7 ソケットオプション

```csharp
public void SetSocketOption(SocketOptionLevel optionLevel, SocketOptionName optionName, int optionValue);
public void SetSocketOption(SocketOptionLevel optionLevel, SocketOptionName optionName, bool optionValue);
public object? GetSocketOption(SocketOptionLevel optionLevel, SocketOptionName optionName);
```

主要なオプション:
- `SocketOptionName.ReuseAddress`: アドレス再利用
- `SocketOptionName.KeepAlive`: キープアライブ
- `SocketOptionName.NoDelay`: Nagle アルゴリズム無効化
- `SocketOptionName.ReceiveTimeout`: 受信タイムアウト
- `SocketOptionName.SendTimeout`: 送信タイムアウト

## 4. エラー処理

### 4.1 例外一覧

| 例外 | 発生条件 |
|------|----------|
| SocketException | ソケット操作エラー |
| ObjectDisposedException | Dispose 後の操作 |
| ArgumentNullException | 必須引数が null |
| ArgumentOutOfRangeException | 引数が範囲外 |
| InvalidOperationException | 不正な操作 |

### 4.2 SocketError 列挙型（主要）

| エラー | 値 | 説明 |
|--------|-----|------|
| Success | 0 | 成功 |
| SocketError | -1 | 一般エラー |
| Interrupted | 10004 | 割り込み |
| AccessDenied | 10013 | アクセス拒否 |
| AddressAlreadyInUse | 10048 | アドレス使用中 |
| ConnectionRefused | 10061 | 接続拒否 |
| TimedOut | 10060 | タイムアウト |
| ConnectionReset | 10054 | 接続リセット |
| NetworkUnreachable | 10051 | ネットワーク到達不可 |
| HostUnreachable | 10065 | ホスト到達不可 |

## 5. セキュリティ考慮事項

### 5.1 ネットワークセキュリティ
- TLS/SSL は NetworkStream + SslStream で実装
- ファイアウォール設定との連携
- DoS 攻撃対策（backlog 設定、タイムアウト）

### 5.2 入力検証
- バッファサイズの制限
- エンドポイント検証

## 6. コードリーディングガイド

### 6.1 推奨読解順序

1. **データ構造の理解**
   - `AddressFamily.cs`: アドレスファミリー列挙
   - `SocketType.cs`: ソケットタイプ列挙
   - `ProtocolType.cs`: プロトコル列挙
   - `EndPoint.cs`: エンドポイント抽象

2. **エントリーポイント**
   - `Socket.cs`: メインクラス
   - **22-70行目**: フィールド定義と状態管理
   - **72-100行目**: コンストラクタ群
   - **260-266行目**: 静的プロパティ（OS サポート確認）
   - **270-291行目**: Available プロパティ

3. **プラットフォーム抽象化**
   - `SocketPal.cs`: プラットフォーム別実装へのブリッジ
   - `SocketPal.Unix.cs`: Unix/Linux 実装
   - `SocketPal.Windows.cs`: Windows 実装

4. **高レベルラッパー**
   - `TcpClient.cs`: TCP クライアント
   - `TcpListener.cs`: TCP サーバー
   - `UdpClient.cs`: UDP クライアント

### 6.2 プログラム呼び出し階層図

```
new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
    │
    └── SocketPal.CreateSocket()
            │
            └── Interop.Socket() [ネイティブ呼び出し]

socket.Connect(remoteEndPoint)
    │
    ├── EndPoint.Serialize()
    │
    └── SocketPal.Connect()
            │
            └── Interop.Connect() [ネイティブ呼び出し]

socket.SendAsync(buffer, flags, ct)
    │
    ├── AwaitableSocketAsyncEventArgs 取得
    │
    ├── SetBuffer(buffer)
    │
    └── SendAsync(saea)
            │
            └── SocketPal.SendAsync()
                    │
                    └── Interop.Send() [非同期I/O]
```

### 6.3 データフロー図

```
┌──────────────────┐
│ アプリケーション   │
│ Socket API       │
└────────┬─────────┘
         │
         ▼
┌──────────────────┐
│ Socket クラス     │
│ 状態管理          │
│ バッファ管理       │
└────────┬─────────┘
         │
         ▼
┌──────────────────┐
│ SocketPal        │
│ プラットフォーム   │
│ 抽象化           │
└────────┬─────────┘
         │
    ┌────┴────┐
    ▼         ▼
┌────────┐ ┌────────┐
│Windows │ │Unix/   │
│Interop │ │Linux   │
│        │ │Interop │
└────┬───┘ └────┬───┘
     │          │
     └────┬─────┘
          ▼
┌──────────────────┐
│ OS カーネル       │
│ ネットワークスタック│
└────────┬─────────┘
         │
         ▼
┌──────────────────┐
│ ネットワーク       │
└──────────────────┘
```

### 6.4 読解のコツ

#### 6.4.1 partial class 構成
Socket クラスは複数ファイルに分割:
- `Socket.cs`: コア機能
- `Socket.Tasks.cs`: Task ベースの非同期メソッド
- `Socket.Unix.cs`: Unix 固有コード
- `Socket.Windows.cs`: Windows 固有コード

#### 6.4.2 状態管理フィールド（Socket.cs: 28-70行目）
```csharp
private SafeSocketHandle _handle;
internal EndPoint? _rightEndPoint;  // Bind 後のエンドポイント
internal EndPoint? _remoteEndPoint; // 接続先エンドポイント
private bool _isConnected;
private bool _isListening;
private bool _willBlock = true;     // ブロッキングモード
```

#### 6.4.3 デュアルスタックモード
IPv6 ソケットで IPv4 も受け入れ可能:
```csharp
socket.DualMode = true;  // IPv6 ソケットで IPv4 も受け入れ
```

### 6.5 関連ファイル一覧

| パス | 種別 | 役割 |
|------|------|------|
| `src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs` | ソース | メインクラス |
| `src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.Tasks.cs` | ソース | Task 非同期メソッド |
| `src/libraries/System.Net.Sockets/src/System/Net/Sockets/TcpClient.cs` | ソース | TCP クライアント |
| `src/libraries/System.Net.Sockets/src/System/Net/Sockets/TcpListener.cs` | ソース | TCP サーバー |
| `src/libraries/System.Net.Sockets/src/System/Net/Sockets/UdpClient.cs` | ソース | UDP クライアント |
| `src/libraries/System.Net.Sockets/src/System/Net/Sockets/NetworkStream.cs` | ソース | Stream ラッパー |
| `src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketPal.cs` | ソース | プラットフォーム抽象 |
| `src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketError.cs` | ソース | エラー列挙 |
| `src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketException.cs` | ソース | 例外クラス |
| `src/libraries/System.Net.Primitives/src/System/Net/EndPoint.cs` | ソース | エンドポイント基底 |
| `src/libraries/System.Net.Primitives/src/System/Net/IPEndPoint.cs` | ソース | IP エンドポイント |

## 7. 使用例

### 7.1 TCP サーバー

```csharp
var listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
listener.Bind(new IPEndPoint(IPAddress.Any, 8080));
listener.Listen(10);

while (true)
{
    var client = await listener.AcceptAsync();
    _ = HandleClientAsync(client);
}

async Task HandleClientAsync(Socket client)
{
    var buffer = new byte[1024];
    while (true)
    {
        var received = await client.ReceiveAsync(buffer, SocketFlags.None);
        if (received == 0) break;
        await client.SendAsync(buffer.AsMemory(0, received), SocketFlags.None);
    }
    client.Dispose();
}
```

### 7.2 TCP クライアント

```csharp
using var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
await socket.ConnectAsync(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8080));

var message = Encoding.UTF8.GetBytes("Hello, Server!");
await socket.SendAsync(message, SocketFlags.None);

var buffer = new byte[1024];
var received = await socket.ReceiveAsync(buffer, SocketFlags.None);
Console.WriteLine(Encoding.UTF8.GetString(buffer, 0, received));
```

### 7.3 UDP 通信

```csharp
using var udp = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
udp.Bind(new IPEndPoint(IPAddress.Any, 9000));

EndPoint remote = new IPEndPoint(IPAddress.Any, 0);
var buffer = new byte[1024];
int received = udp.ReceiveFrom(buffer, ref remote);

Console.WriteLine($"From {remote}: {Encoding.UTF8.GetString(buffer, 0, received)}");
```

## 8. テスト観点

### 8.1 単体テスト観点
- 各 AddressFamily での動作
- TCP/UDP プロトコルの動作
- 同期/非同期メソッドの動作
- エラーハンドリング

### 8.2 結合テスト観点
- クライアント・サーバー間通信
- ネットワーク障害時の動作
- 高負荷時の動作

### 8.3 性能テスト観点
- スループット測定
- 同時接続数の影響
- メモリ使用量

## 9. 変更履歴

| バージョン | 日付 | 変更内容 |
|------------|------|----------|
| 1.0 | 2026-01-30 | 初版作成 |
