1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ソケットの概要 (走り書き)

Last updated at Posted at 2024-11-16

この記事は?

ソケットについて調べた際の走り書きです。

調べた動機

  • HTTP - (ソケット?) - TCP - IP - …
  • MySQL の /tmp/mysql.sock もソケット?
OSI 参照モデル

OSI参照モデル > 例 > 層別の例 - Wikipedia より

内容

  • ソケット: ネットワーク通信に用いるファイルディスクリプタ (file descriptor)
  • UNIX 系 OS (Linux など) では入出力はすべてバイト列として扱われる。その入出力ではバイト列のことをストリーム (stream) と呼ぶ
  • ファイルディスクリプタ: ストリームを区別する識別子 (整数)
    • 0: 標準入力
    • 1: 標準出力
    • 2: 標準エラー出力
    • そのほかのストリームはオープンされるたびに小さい番号から順に使われクローズされると同じ番号が再利用される
  • ファイルディスクリプタが対応しているストリームの接続先がローカルのファイルやネットワーク経由の接続というように種類が異なっていても、全く同じように入出力できる
    • つまりストリームを透過的に扱える
    • ソケットではファイルに対する操作と同様の操作でネットワーク通信を進められる
プロトコルファミリー
ソケットタイプ
SOCK_STREAM SOCK_DGRAM 特定方法 通信
AF_INET
AF_INET6
TCP UDP IP アドレス
ポート番号
ホスト間
AF_UNIX UNIX ドメインソケット UNIX ドメインソケット ファイル名 プロセス間
  • ソケットの種類
    • INET ドメインソケットと UNIX ドメインソケット
  • 特定方法
    • TCP: 5 タプル (プロトコル、送信側 IP、送信側ポート、受信側 IP、受信側ポート)
    • UNIX ドメインソケット:
      • MySQL サーバーがローカルクライアントと通信するために使用する UNIX ソケットファイルのデフォルトの場所は /tmp/mysql.sock である
  • プロトコルファミリー
    • AF_INET: IPv4 インターネットプロトコル
    • AF_INET6: IPv6 インターネットプロトコル
    • AF_UNIX: ローカル通信
  • ソケットタイプ
    • SOCK_STREAM: 順序性と信頼性があり、双方向の接続されたバイトストリームを提供する
      • 帯域外データ転送メカニズムもサポートする
    • SOCK_DGRAM: データグラムをサポートする
      • データグラム (datagram): 配送成功・到達時間・到達順序がネットワークサービスによって保証されることがないパケット交換網における基本転送単位
  • ソケットによる通信を行う際に使用するシステムコール
    • システムコール: アプリケーションと Linux カーネルとの間の基本的なインターフェース。
    • socket(), bind(), listen(), accept(), read(), write(), close()
      • ソケットはファイルディスクリプタなので、通常のファイルに対する場合と同様に read(), write() が使える
TCP Server and TCP Client

Chapter 4. Elementary TCP Sockets - Shichao's Notes より

Ruby でソケットを扱ってみる。

require 'socket'

# TCP Server
server = TCPServer.new(12_345)

loop do
  # TCPServer#accept
  # クライアントからの接続要求を受け付け、接続した TCPSocket のインスタンスを返す。
  socket = server.accept
  socket.print(Time.now.strftime('%Y/%m/%d (%a) %H:%M:%S'))
  socket.close
end
require 'socket'

# TCP Client
TCPSocket.open('localhost', 12_345).read
#=> "2024/11/16 (Sat) 21:30:31"

# サーバを閉じた後。
TCPSocket.open('localhost', 12_345).read
# Connection refused - connect(2) for "localhost" port 12345 (Errno::ECONNREFUSED)
$ lsof -i:12345
COMMAND   PID         USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
ruby    20178       quanon    8u  IPv4 0x9db00af21468648e      0t0  TCP localhost:61265->localhost:italk (CLOSE_WAIT)
ruby    20482       quanon   10u  IPv6  0x2c83fda6bc3c44f      0t0  TCP *:italk (LISTEN)
require 'socket'

# TCP Server
server = UNIXServer.new('/tmp/sock')

loop do
  socket = server.accept
  socket.print(Time.now.strftime('%Y/%m/%d (%a) %H:%M:%S'))
  socket.close
end
require 'socket'

# TCP Client
UNIXSocket.open('/tmp/sock').read
#=> "2024/11/16 (Sat) 21:31:40"

# サーバを閉じた後。
UNIXSocket.open('/tmp/sock').read
# Connection refused - connect(2) for /tmp/sock (Errno::ECONNREFUSED)

参考

記事

書籍

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?