6.93. kink/socket/TCP¶
ストリームベースのコネクティングソケットを提供する。
例
次のプログラムは、TCP/IPのサーバとクライアントを立ち上げる。クライアントはTCP_NODELAY, SO_SNDBUF, SO_LINGERのソケットオプションを設定し、バイト列 [1, 2, 3] をサーバに送る。
:TCP.require_from('kink/socket/')
:TCP_SERVER.require_from('kink/socket/')
:IP.require_from('kink/socket/')
:IP_PORT.require_from('kink/socket/')
:THREAD.require_from('kink/thread/')
:BIN.require_from('kink/')
:CONTROL.require_from('kink/')
:spawn_client <- {(:Server_addr)
THREAD.spawn_io{
CONTROL.with_finally{(:finally)
:Tcp = TCP.open
finally{ Tcp.close }
# initial socket options
stdout.print_line(Tcp.tcp_nodelay.load.repr) # => false
stdout.print_line(Tcp.so_sndbuf.load.repr) # => 8192 (initial values vary for systems)
stdout.print_line(Tcp.so_linger.load.repr) # => []
# set socket options
Tcp.tcp_nodelay <- true
Tcp.so_sndbuf <- 1024
Tcp.so_linger <- [10]
stdout.print_line(Tcp.tcp_nodelay.load.repr) # => true
stdout.print_line(Tcp.so_sndbuf.load.repr) # => 2304 (the value was adjusted)
stdout.print_line(Tcp.so_linger.load.repr) # => [10]
Tcp.connect(Server_addr)
:Out = Tcp.output
finally{ Out.close }
Out.write(BIN.of(1))
Out.write(BIN.of(2))
Out.write(BIN.of(3))
}
}
}
CONTROL.with_finally{(:finally)
:Server = TCP_SERVER.open
finally{ Server.close }
Server.bind_listen(IP_PORT.new(IP.for_hostname('::1') 0))
:Server_addr = Server.local_address
spawn_client(Server_addr)
:Tcp = Server.accept
finally{ Tcp.close }
:In = Tcp.input
finally{ In.close }
:Bin = In.read_all
stdout.print_line(Bin.repr) # => (bin 0x01 0x02 0x03)
}
6.93.1. tcp型¶
tcpはストリームベースのコネクティングソケットである。プロトコルは、TCP/IPか、ストリームベースのUnixドメインソケットのどちらかである。
6.93.1.1. Tcp.connect(Remote ...[$config={}])¶
connectはソケットを、Remoteで指定されたリモートアドレスに接続する。
コンフィグメソッド:
• C.on_success($success): default = {}
• C.on_error($error): default = {(:Exc) Exc.raise }
• C.on_closed($closed): default = $errorを末尾呼び出しするサンク
connectは、接続が確立するか、ソケットが閉じられるか、IOエラーが発生するまで待つ。
接続が確立した場合、connectは$successを引数なしで末尾呼び出しする。クライアントはソケットからデータを読んだり、ソケットにデータを書いたりできる。
connectの呼び出しの前、または呼び出し中に、コネクティングソケットが閉じられた場合、connectは$closedを引数なしで末尾呼び出しする。
IOエラーが起きた場合、connectはコネクティングソケットを閉じて、exceptionを引数として$errorを末尾呼び出しする。
タイムアウト
接続タイムアウトは、C.on_closedとTcp.close_unless_connectedで実装できる。
:TCP.require_from('kink/socket/')
:IP.require_from('kink/socket/')
:IP_PORT.require_from('kink/socket/')
:THREAD.require_from('kink/thread/')
:CONTROL.require_from('kink/')
:PROCESS.require_from('kink/')
CONTROL.with_finally{(:finally)
:Tcp = TCP.open
finally{ Tcp.close }
# a blackhole address. see RFC 6666
:Blackhole = IP_PORT.new(IP.for_hostname('0100::1234') 8080)
# times out connection after 10 seconds
THREAD.spawn_io{
THREAD.sleep(10)
Tcp.close_unless_connected
}
# exits the process when connection times out
Tcp.connect(Blackhole){(:C)
C.on_closed{
stderr.print_line('connection time out')
PROCESS.exit(76)
}
}
}
# => connection time out
ランタイムやオペレーティングシステムも、それぞれ接続のタイムアウトを行うかもしれない。この場合、$closedが末尾呼び出しされる代わりに、IOエラーが起きるかもしれない。
事前条件
Remoteはsocket_addressであり、ソケットのプロトコルファミリと合致しなければならない。
$successはサンクでなければならない。
$errorはexceptionを引数に取る関数でなければならない。
$closedはサンクでなければならない。
6.93.1.2. Tcp.bind(Local ...[$config])¶
bindは、Localで指定されたローカルアドレスをソケットに束縛する。
コンフィグメソッド:
• C.on_success($success): default = {}
• C.on_error($error): default = {(:Exc) Exc.raise }
アドレスが成功裏に束縛された場合、bindは引数なしで$successを末尾呼び出しする。
IOエラーが起きた場合、bindはexceptionを渡して$errorを末尾呼び出しする。
事前条件
Localはsocket_addressであり、ソケットのプロトコルファミリと合致しなければならない。
$successはサンクでなければならない。
$errorはexceptionを引数に取る関数でなければならない。
6.93.1.3. Tcp.close(...[$config={}])¶
closeはコネクティングソケットを閉じる。
コンフィグメソッド:
• C.on_success($success): default = {}
• C.on_error($error): default = {(:Exc) Exc.raise }
ソケットが成功裏に閉じられた場合、closeは$successを引数なしで末尾呼び出しする。
IOエラーが起きた場合、closeは、exceptionを引数として$errorを末尾呼び出しする。
事前条件
$successはサンクでなければならない。
$errorはexceptionを引数に取る関数でなければならない。
6.93.1.4. Tcp.close_unless_connected(...[$config={}])¶
close_unless_connectedは、ソケットが接続されていない場合に限って、コネクティングソケットを閉じる。ソケットが接続されている場合、またはすでに閉じられている場合、close_unless_connectedは何もしない。
コンフィグメソッド:
• C.on_success($success): default = {}
• C.on_error($error): default = {(:Exc) Exc.raise }
ソケットが接続されている場合、またはすでに閉じられている場合、close_unless_connectedは引数なしで$successを末尾呼び出しする。
ソケットが接続されていない場合、close_unless_connectedはソケットを閉じる。成功した場合、close_unless_connectedは引数なしで$successを末尾呼び出しする。IOエラーが起きた場合、close_unless_connectedは、exceptionを引数として$errorを末尾呼び出しする。
事前条件
$successはサンクでなければならない。
$errorはexceptionを引数に取る関数でなければならない。
6.93.1.5. Tcp.input(...[$config={}])¶
inputメソッドはコネクティングソケットからinputを作る。
コンフィグメソッド:
• C.buffer(...[Max_buf_size])
C.bufferが呼ばれた場合、結果のinputはユーザ空間でのバッファリングを行う。Max_buf_sizeが渡された場合、バッファサイズはMax_buf_sizeを超えない。C.bufferが呼ばれなければ、inputはユーザ空間でのバッファリングを行わない。
inputを閉じると、ソケットの入力ストリームが遮断される。
事前条件
Max_buf_sizeは正の整数のnum値でなければならない。
6.93.1.6. Tcp.output(...[$config={}])¶
outputメソッドはコネクティングソケットからoutputを作る。
コンフィグメソッド:
• C.buffer(...[Max_buf_size])
C.bufferが呼ばれた場合、結果のoutputはユーザ空間でのバッファリングを行う。Max_buf_sizeが渡された場合、バッファサイズはMax_buf_sizeを超えない。C.bufferが呼ばれなければ、outputはユーザ空間でのバッファリングを行わない。
outputを閉じると、ソケットの出力ストリームが遮断される。
事前条件
Max_buf_sizeは正の整数のnum値でなければならない。
6.93.1.7. Tcp.local_address(...[$config={}])¶
local_addressは、コネクティングソケットのローカルアドレスのsocket_addressを取得する。
コンフィグメソッド:
• C.on_success($success): default = VAL.identity
• C.on_error($error): default = {(:Exc) Exc.raise }
ローカルアドレスがある場合、local_addressは、socket_addressを引数として$successを末尾呼び出しする。
IOエラーが起きた場合、local_addressは、exceptionを引数として$errorを末尾呼び出しする。
事前条件
$successは、socket_addressを引数に取る関数でなければならない。
$errorはexceptionを引数に取る関数でなければならない。
6.93.1.8. Tcp.remote_address(...[$config={}])¶
remote_addressは、コネクティングソケットのリモートアドレスのsocket_addressを取得する。
コンフィグメソッド:
• C.on_success($success): default = VAL.identity
• C.on_error($error): default = {(:Exc) Exc.raise }
リモートアドレスがある場合、remote_addressは、socket_addressを引数として$successを末尾呼び出しする。
IOエラーが起きた場合、remote_addressは、exceptionを引数として$errorを末尾呼び出しする。
事前条件
$successは、socket_addressを引数に取る関数でなければならない。
$errorはexceptionを引数に取る関数でなければならない。
6.93.1.9. Tcp.tcp_nodelay¶
tcp_nodelayは、TCP_NODELAYオプションのbool値のrefを戻す。
ソケットオプションの使い方については、このモジュールの先頭の例示のプログラムを見よう。
事前条件
プロトコルファミリはipv4かipv6でなければならない。
6.93.1.10. Tcp.so_keepalive¶
so_keepaliveは、SO_KEEPALIVEオプションのbool値のrefを戻す。
ソケットオプションの使い方については、このモジュールの先頭の例示のプログラムを見よう。
事前条件
プロトコルファミリはipv4かipv6でなければならない。
6.93.1.11. Tcp.so_reuseaddr¶
so_reuseaddrは、SO_REUSEADDRオプションのbool値のrefを戻す。
ソケットオプションの使い方については、このモジュールの先頭の例示のプログラムを見よう。
事前条件
プロトコルファミリはipv4かipv6でなければならない。
6.93.1.12. Tcp.so_linger¶
so_lingerは、SO_LINGERオプションを表す、オプショナルな非負な整数のnum値のrefを戻す。
refの値は、空のvecか、 一要素のvec [l_linger] のいずれかである。ここでl_lingerは、非負の整数のnumである。値が空のvecのとき、SO_LINGERオプションは無効にされる。値が一要素のvecのとき、SO_LINGERは有効になり、l_lingerがタイムアウト秒数になる。
ソケットオプションの使い方については、このモジュールの先頭の例示のプログラムを見よう。
事前条件
プロトコルファミリはipv4かipv6でなければならない。
6.93.1.13. Tcp.so_sndbuf¶
so_sndbufは、SO_SNDBUFオプションの、非負な整数のnum値のrefを戻す。
ソケットオプションの使い方については、このモジュールの先頭の例示のプログラムを見よう。
6.93.1.14. Tcp.so_rcvbuf¶
so_rcvbufは、SO_RCVBUFオプションの、非負な整数のnum値のrefを戻す。
ソケットオプションの使い方については、このモジュールの先頭の例示のプログラムを見よう。
6.93.2. TCP.open(...[Protocol_family=PROTOCOL_FAMILY.ipv6 $config={}])¶
openは、新しいコネクティングソケットを作る。
コンフィグメソッド:
• C.on_success($success): default = VAL.identity
• C.on_error($error): default = {(:Exc) Exc.raise }
• C.on_unsupported($unsupported): default = $erroを末尾呼び出しする関数
ソケットが作られた場合、openは、tcpを引数として$successを末尾呼び出しする。
指定されたプロトコルファミリをランタイムがサポートしない場合、openは引数なしで$unsupportedを末尾呼び出しする。
IOエラーが起きた場合、openは、exceptionを引数として$errorを末尾呼び出しする。
事前条件
Protocol_familyはprotocol_familyでなければならない。
$successは、tcpを取る関数でなければならない。
$errorはexceptionを引数に取る関数でなければならない。
$unsupportedはサンクでなければならない。
6.93.3. TCP.is?(Val)¶
is?は、Valがtcp値であるかどうかを戻す。