📝゜ケットプログラミング抂論

📝゜ケットプログラミング抂論

August 17, 2022

゜ケットプログラミングずは #

゜ケット(Socket) #

実行䞭のプログラム間でデヌタの送受信を行うための暙準的なプログラミングむンタヌフェヌス (API) の䞀぀.

TCP/IP アプリケヌションを䜜成するための抜象化されたむンタヌフェヌス

ref. ゜ケット (BSD) - Wikipedia

EndPoints #

端末.䞀意に定たる通信先.

Socket は IP Address ず PortNo.を぀かっお, 通信先の゜ケットを特定する. ネットワヌクに接続されたパ゜コンや PDA, 携垯電話などのネットワヌク端末の総称. ゚ンドボむントに Socket がバむンドされる.

Loopbacks #

IP アドレスは必ずしもリモヌトホストず関連付けられおいる必芁はない. ずくに開発環境では, ロヌカルな IP アドレスが圹に立぀.

自端末に察しお通信するこずを LoopBack ずいう. LoopBack で指定するアドレスを Loopback Address ずいう.

  • ハヌドりェアず関係ない, 論理的なむンタフェヌス.
  • Linux では, localhost ず蚀われおいる. IP は 127.0.0.1

ref. ルヌプバックずは 〔 ロヌカルルヌプバック 〕

Ports #

ポヌトフォワヌディング #

ロヌカルコンピュヌタの特定のポヌトに送られおきたデヌタを別に甚意した通信経路を甚いおリモヌトコンピュヌタの特定ポヌトに送信するこず.

ref. ポヌトフォワヌディングずは 【 port forwarding 】

たずえば, Windows ファむルサヌバに,SSH 経由で (CIFS, port 445/tcp で) アクセスする (した).

Stream #

デヌタの入力たたは出力の機胜を提䟛する抜象デヌタ型. メッセヌゞの境界ずいう境界がない. TCP/IP プロトコルはストリヌムベヌスの蚭蚈.

ref. ストリヌム (プログラミング) - Wikipedia

Blocking/Non-Blocking #

ブロッキング #

送受信の完了を埅っおから他の凊理を開始する通信方法.

require 'socket'
server = TCPServer.new (2803)
while client = server.accept
  input = client.readline
  client.write "You said: #{input}"
  client.close
end

ノン・ブロッキング #

デヌタの送受信を行う際に, 送受信の完了を埅たず他の凊理を開始する通信方法.

ref. ノンブロッキング通信ずは 〔 ノンブロッキングモヌド 〕

require 'socket'
server = TCPServer.new (2803)
loop do
  Thread.new (server.accept){ |client|
    input = client.readline
    client.write "You said: #{input}"
    client.close
  }
end

Example Ruby #

Server Lifecycle #

  1. create ゜ケットの生成

  2. bind

    • ゜ケットを利甚する Port にバむンド.
      • User でバむンドする Port は 1025-48999
    • ゜ケットが通信を蚱可する IP を指定.
    • 0.0.0.0: すべお蚱可
    • 127.0.0.1: 自端末のみ蚱可
    • xxx.xxx.xxx.xxx: ある端末のみ蚱可
  3. listen 通信先゜ケットからの通信をた぀

  4. accept 通信先゜ケットからの通信を受け取り, 通信路 をその぀ど生成 (connection)

  5. close 通信元゜ケットの消滅.

# coding: utf-8
require 'socket'

# 1. create
server = Socket.new (:INET, :STREAM)

# 2. bind
addr = Socket.pack_sockaddr_in (4481, "0.0.0.0")
server.bind (addr)

# 3. listen
server.listen (5)

# 4. accept
loop do
  connection, _ = server.accept

  ## send message from client.
  # ehco "Hello" | nc localhost 4481
  p connection

  # it should be closed each connection
  connection.close
end

# 5. close
server.close

TCPServer #

Ruby では, 以䞋のような糖衣構文がある.

ref. class TCPServer

server = TCPServer.new (4481)
# =>
# server = Socket.new (:INET, :STREAM)
# addr = Socket.pack_sockaddr_in (4481, "0.0.0.0")
# server.bind (addr)
# server.listen (5)

Client LifeCycle #

  1. create ゜ケットの生成

(2. bind )

  1. connect サヌバず接続
  2. close ゜ケットの砎棄
require 'socket'

# 1. create
socket = Socket.new (:INET, :STREAM)

# 3. connect
remote_addr = Socket.pack_sockaddr_in (80, 'google.com')
socket.connect (remote_addr)

# 4. close
socket.close

TCPSocket #

Ruby では, 以䞋のような糖衣構文がある.

ref. class TCPSocket

socket = TCPSocket.new ('google.com', 80)
# =>
# socket = Socket.new (:INET, :STREAM)
# remote_addr = Socket.pack_sockaddr_in (80, 'google.com')
# socket.connect (remote_addr)

Simple Read #

以䞋の䟋では, 氞遠にサヌバは Read を埅ち続けお, その先が進たない.

require 'socket'

Socket.tcp_server_loop (4481) do |connection|
  puts connection.read
  connection.close
end

Socket は指定されたデヌタ長のデヌタが到着するたで埅ち続ける. デッドロックを回避するためには,

  • Client 偎で デヌタの最埌で EOF を送信する.(EOF event)
  • Server 偎で䞀床に読み蟌むデヌタ長を小さくする. (partial read)

Client の゜ケットが close メ゜ッドを実行するず, その延長で EOF が通知される.

SocketTimeout/Connection Timeout/Connection Request Timeout #

JavaのApache HttpClentの䜿甚だがいろんな蚀語実装で登堎するのでたずめおおく. 蚭定可胜な぀の属性の意味はそれぞれ以䞋の通り.

  • socket timeout: ゜ケット通信のスタヌトから終了たで.
  • connection timeout: クラむアントからサヌバぞの接続確立(3way-shake)たで
  • connection-request-timeout: 接続確立埌からレスポンスが返るたで.

ref. JavaのHttpClientにおける3぀のTimeoutの違いに関しお - Qiita

゚ラヌが発生したずきの障害解析で倧事なのは, 自分が悪いのかサヌバが悪いのかずいう問題.

Connection Timeoutはサヌバぞの通信が届いおないのでサヌバは悪くない. Socket Timeoutはサヌバからの通信か切れたのでサヌバが悪いかも.

connection timeoutは3の倍数 #

TCPの仕様で3秒ごずに状況確認をするようで, 3の倍数で蚭定するのがよいずのこず.

【Python】requestsを䜿うずきは必ずtimeoutを蚭定するべき | Cosnomi Blog

Broken pipe #

よくssh接続ずかで芋かけるや぀. プログラムを動かしおいお通信゚ラヌでもでる.

packet_write_wait: Connection to port 22: Broken pipe

Broken pipeず出力される原因はクラむアントからサヌバ(ssh接続先)に察しお䞀定時間無操䜜ためタむムアりトにより切断されたず思われたす.

これはクラむアント偎が被疑箇所の可胜性. サヌバからの応答完了を埅たずに接続終了. しかし応答を埅っおいるのが期埅時間倖あればサヌバが被疑箇所の可胜性もある. いずれにしろリトラむによっお救枈を詊みるこずがよい.

References #