0Pricing
Lua Academy · レッスン

TCPの基本

接続してデータを送信します。

「TCPの基本」はCoddyKit上の無料Lua Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはLua Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Lua Academyコースには全4レッスンが含まれています。

LuaSocket とは

LuaSocket は Lua のデファクトスタンダードなネットワークライブラリです。生の TCP および UDP ソケットに加えて、HTTP、SMTP、FTP 用の高レベルヘルパーも提供します。

これは外部の C モジュールであるため、標準の Lua には含まれていません。LuaRocks 経由でインストールし、require で読み込みます。

ネットワークにアクセスするため、このコースのスニペットは通常のプレイグラウンドでは実行できません。

local socket = require("socket")
print(socket._VERSION)

TCP ソケットの作成

基本となるオブジェクトは TCP マスターソケットで、socket.tcp() で作成します。新しく作成したマスターソケットは、接続もバインドもされていません。

マスターソケットからは、connect してクライアントオブジェクトにするか、bind と listen を使ってサーバーオブジェクトにすることができます。

多くの呼び出しは、値を返すか、エラー文字列とともに nil を返します。そのため、必ず両方を受け取ってください。

local socket = require("socket")
local tcp, err = socket.tcp()
if not tcp then error(err) end

アドレスファミリー

TCP は IPv4 または IPv6 上で動作します。socket.tcp() は必要になったときにアドレスファミリーを選択しますが、socket.tcp4() と socket.tcp6() では一方を明示的に指定できます。

明示的に制御する必要がある場合は、接続前に socket.dns.toip(host) を使ってホスト名を数値アドレスに解決します。

local socket = require("socket")
local ip, info = socket.dns.toip("example.com")
print(ip)

ホストへの接続

conn:connect(host, port) は TCP の3ウェイハンドシェイクを実行します。成功すると 1 を返し、失敗すると nil と、"connection refused" や "timeout" などのエラーメッセージを返します。

便利な関数 socket.connect(host, port) を使うと、ソケットの作成と接続を1回の呼び出しで行えます。

local socket = require("socket")
local conn, err = socket.connect("example.com", 80)
if not conn then print("failed:", err) end

データの送信

conn:send(data) はソケットにバイトを書き込みます。送信した最後のバイトのインデックスを返します。ブロッキングソケットでは、通常 data の長さ全体が送信されます。

TCP はメッセージプロトコルではなくバイトストリームです。そのため、1回の send が通信中に分割されたり、複数回の送信がまとめられたりすることがあります。メッセージのフレーミングは自分で行う必要があります。

local request = "GET / HTTP/1.0\r\n\r\n"
local sent, err = conn:send(request)
print("bytes sent:", sent)

データの受信

conn:receive(pattern) はストリームから読み取ります。デフォルトのパターン "*l" は改行を除く1行を読み取ります。"*a" は接続が閉じられるまで読み取ります。

数値を渡して、そのバイト数を正確に読み取ることもできます。エラーが発生した場合は、nil、エラー文字列、そして受信済みの部分データを返します。

local line, err = conn:receive("*l")
local chunk = conn:receive(512)
local all = conn:receive("*a")

接続を閉じる

処理が終わったら、必ず conn:close() を呼び出してください。これによりファイルディスクリプターが解放され、TCP FIN が送信されます。

conn:shutdown("send") を使うと、送信方向だけを閉じ、相手の応答を読み続けることができます。"*a" を使うリクエスト/レスポンス型のプロトコルで便利です。

conn:shutdown("send")
local reply = conn:receive("*a")
conn:close()

タイムアウトの重要性

デフォルトでは、ソケットは永久にブロックします。conn:settimeout(seconds) で、呼び出しが待機できる時間に上限を設定できます。値を 0 にすると、ソケットはノンブロッキングになります。

タイムアウトになると、呼び出しは nil と文字列 "timeout" を返します。本番環境では、接続がハングするのを防ぐために必ずタイムアウトを設定してください。

conn:settimeout(5)
local data, err = conn:receive("*l")
if err == "timeout" then print("too slow") end

TCPとUDPの比較

TCPはコネクション指向で、順序が保証され、信頼性があります。バイトは一度だけ、順番どおりに届きますが、その代わりにハンドシェイクや再送が必要です。

UDP(socket.udp())はコネクションレスで信頼性はありませんが軽量で、テレメトリやゲームに適しています。このコースでは、HTTPの基盤となるTCPに焦点を当てます。

部分送信とループ

ノンブロッキングソケットでは、sendがバッファの一部しか送信しない場合があります。このメソッドは、これまでに書き込まれた最後のバイトのインデックスとともに、nilまたは"timeout"を返します。

堅牢な送信処理では、最後に送信したバイトの次のバイトから再開し、バッファ全体を送信し終えるまでループします。

local i = 1
while i <= #data do
  local sent, err, last = conn:send(data, i)
  i = (sent or last) + 1
  if err and err ~= "timeout" then break end
end

接続の確認

conn:getpeername()はリモートのIPアドレスとポートを返し、conn:getsockname()はローカル側の情報を返します。これらはログ出力やデバッグに役立ちます。

conn:setoption("keepalive", true)とconn:setoption("tcp-nodelay", true)を使うと、基盤となるソケットの動作を調整できます。

local ip, port = conn:getpeername()
print("connected to", ip, port)
conn:setoption("tcp-nodelay", true)

理解度チェック

TCPの受信セマンティクスについての理解を確認しましょう。

まとめ

LuaSocketのTCPマスターオブジェクトについて学び、ソケットの作成、接続、送信、受信、クローズの方法を習得しました。また、タイムアウトとハーフクローズが動作にどのような影響を与えるかも確認しました。

TCPはバイトストリームであり、すべての呼び出しがnil, errを返す可能性があり、本番環境のソケットでは必ずタイムアウトを設定することを覚えておいてください。次は、これらの要素を組み合わせて動作するクライアントを作成します。

よくある質問

「TCPの基本」レッスンは無料ですか?

はい。「TCPの基本」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Lua Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Lua Academyコースには全4レッスンが含まれています。

「TCPの基本」で何を学びますか?

接続してデータを送信します。 ブラウザで直接実行するハンズオンコードでLua Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Lua Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのLua Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。

「TCPの基本」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このLua Academyレッスンでコードを書いて実行できますか?

はい。すべてのLua Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. TCPの基本
  2. クライアントを構築する
  3. サーバーを構築する
  4. HTTPリクエスト
← Lua Academyに戻る