mai のプロトコル 【この文章で使っている記号】------------------------------------------- [D]: パケット区切り文字(0x01) [E]: パケット終端文字 (0x00) 【はじめに】----------------------------------------------------------- 全てのパケットは パケット識別文字列[D]パラメータ[D]パラメータ[D]パラメータ...[E] ^^^^^^^^^^^^^^^^^^ という構造をしています。例えばパケット識別文字列が "DATA" のものを 「DATAパケット」と呼びます。 パラメータが数値の場合は10進数文字列です。パラメータが文字列の場合は EUC の2バイト文字が含まれる場合があります。 [サーバ→クライアント][クライアント→サーバ]の両方で使われているパケッ ト識別文字列("INFO","MES","SESSIONS" など)がありますが、これらはたまたま名前が同 じだけで、パケット識別文字列以降のフォーマットが違いますので注意して ください。 【簡単な mai クライアントの作り方】 ------------------------------------------- クライアントはサーバに接続したら、サーバに DATA パケット(下記の【クライアント→サーバ のパケット一覧】参照)を送ってください。 送ったら、ユーザのキー入力待ち & サーバからのパケット待ちループに入ってください。 [サーバから送られてきたパケットの処理] ・INFO(サーバ→クライアント) パケット セッションのメンバー構成が変わった時に送られてきますので メンバーのユーザ情報を更新してください。最初にクライアントからサーバに  DATA パケットを送ると、サーバからこのINFOパケットが送り返されてきます。 ・MES(サーバ→クライアント) パケット セッションに参加しているメンバー(自分も含む)が文字を入力 したときに送られてきますので、その時はそのユーザのウイン ドウに文字を表示する処理が必要です。 ・CLOSE(サーバ→クライアント) パケット サーバからの切断要求ですので、これを受け取ったら、ソケットを close() して TCP コネクションを切断してください。 これ以外のパケットはとりあえず無視しても構いません。 [ユーザからのキー入力処理] ・キー入力 ユーザのキー入力があった時は、MES(クライアント→サーバ)  パケットを使って、サーバに入力された文字を送信してください。 ・切断 セッションを抜けるときはソケットを close() してコネクショ ンを切断してください。 これだけでmaiクライアントになります。 【クライアントから送信できる文字】------------------------------------------- 0x00 と 0x01 はパケット区切り記号に使います。 0x07 は BEEP 文字です。 0x08 は バックスペース文字です。直前の1文字が半角の時は直前の1バイト (全角の時は2バイト)を消去します。クライアントを作る際は、0x08 が送ら れてきたときには、直前の1バイト(全角の時は2バイト)を消去する処理が必 要になります。 0x0d(CR) は改行コードです。改行には 0x0a(LF) や 0x0d 0x0a(CR LF) は使 えません。 これ以外の 0x1F 以下の文字はクライアントからサーバには送信できません。 【クライアント→サーバ のパケット一覧】------------------------------------------- ・DATA パケット DATA[D]自分のユーザ名@自分のマシン名[D]自分のmaiハンドル名[D]呼び出す相手のユーザ名[E] (例) DATA[D]hoshi@gamera[D]miruku[D]ushio[E] サーバに接続したらまずこの情報を送ります。ユーザ名は UNIX のログイン名です。 maiハンドルは mai で使用する名前です。呼び出す相手のユーザ名は UNIX のログイン名 です。呼び出す相手のユーザ名は省略可能で、省略すると現在自分が呼ばれているセッシ ョン(あれば)に参加します。 呼び出す相手のユーザ名としてセッションID(10進数値)を指定すると、そのセッションに 乱入します。 ・MES パケット(サーバ→クライアントの同名パケットもありますので注意) MES[D]文字列[E] (例1) MES[D]k[E] MES[D]o[E] MES[D]n[E] MES[D]b[E] MES[D]a[E] MES[D]n[E] MES[D]h[E] MES[D]a[E] (例2) MES[D]こんばんは[E] キー入力があったとき、クライアントからその文字をサーバに送るために使います。 ・INFO パケット(サーバ→クライアントの同名パケットもありますので注意) INFO[E] (例) INFO[E] サーバに INFO パケットを送り返すように、明示的に要求します。 明示的に要求しなくても、自分が DATA パケットを送ったとき、セッション の参加人数が変わったときにはサーバから送られてきます。 ・CALL パケット CALL[D]相手ユーザ名[E] (例) CALL[D]hoshi[E] 会話中に他のユーザを呼び出すときに送信します。ユーザ名はサーバマシンの UNIX のログイン名です。 ・CANCEL パケット CANCEL[D]相手ユーザ名[E] (例) CANCEL[D]hoshi[E] CALL での他のユーザの呼び出しを中止するときに送信します。 ・SESSIONS パケット(サーバ→クライアントの同名パケットもありますので注意) SESSIONS[E] (例) SESSIONS[E] サーバに SESSIONS パケットを送り返すように要求します。 ・LOCK パケット LOCK[D]ロックレベル[E] (例) LOCK[D]1[E] 参加中のセッションのロックレベルを設定します。 ロックされたセッションには乱入できません。 ロックレベル=0: ロックを解除する ロックレベル=1: ロックする ・MYSESSIONID パケット [mai Version 2.27 から追加] MYSESSIONID[E] クライアントがサーバーに YOURSESSIONID パケットを要求するために 使用します。 (例) MYSESSIONID[E] ・MYMEMBERID パケット [mai Version 2.27 から追加] MYMEMBERID[E] クライアントがサーバーに YOURMEMBERID パケットを要求するために使 用します。 (例) MYMEMBERID[E] 【サーバ→クライアントのパケット一覧】------------------------------------------- ・INFO パケット (クライアント→サーバの同名パケットもありますので注意) INFO[D]人数[D]ユーザ番号[D]ユーザ名[D]ハンドル[E] -------------------------------- 人数分繰り返し (例) INFO[D]2[D]1[D]hoshi@gamera[D]miruku[D]2[D]ushio@koringo[D]etsuko[E] クライアントから要求があったときとセッション参加メンバーの人数が変わったと きにサーバから送られてきます。ユーザ番号はそのメンバーを識別するためのユー ザ固有の数値で、同一セッション中では同じ値は使われません。ユーザの情報は人 数分繰り返し送られてきますが、そのとき自分のクライアント自身の情報が一番先 頭になるように、ユーザの順番がソートされています。 ・MES パケット(クライアント→サーバの同名パケットもありますので注意) MES[D]ユーザ番号[D]文字列[E] (例) MES[D]1[D]こんばんは[E] 同一セッションに参加しているユーザ(自分自身を含む)が送信した文字列です。 どのユーザからのメッセージかはユーザ番号で識別します。 ・CLOSE パケット CLOSE[D]文字列[E] (例) CLOSE[D]呼ばれていません[E] (1)セッションが終了した場合、(2)呼び出すユーザを指定しなかった場合で誰から も呼ばれていなかった場合、にTCP コネクションを切って欲しいというサーバから の要求です。文字列には切断要求の理由が書かれています。 ・SYSMES パケット SYSMES[D]文字列[E] (例) SYSMES[D]hoshi さんを呼び出しています[E] システムからのお知らせ文字列です。ユーザを呼び出したとき、呼び出しをキャ ンセルしたときなどに、その結果が送られてきます。 ・YOURSESSIONID パケット [mai Version 2.27 から追加] YOURSESSIONID[D]session-id[E] クライアントが送信した MYSESSIONID パケットに対する、サーバーの応答パケ ットです。クライアントが参加中のセッションのセッション識別子の通知に使 用します。 パラメータ session-id クライアントが参加中のセッションのセッション識別子です。クライアントが セッションに参加していない場合、session-id は空文字列です。 (例)YOURSESSIONID[D][E] (例)YOURSESSIONID[D]50[E] ・YOURMEMBERID パケット [mai Version 2.27 から追加] YOURMEMBERID[D]member-id[E] クライアントが送信した MYMEMBERID パケットに対する、サーバーの応答パケッ トです。セッションにおけるクライアントのメンバー識別子の通知に使用します。 パラメータ member-id クライアントが参加中のセッションにおける、クライアント自身のメンバー識別 子です。クライアントがセッションに参加していない場合、member-id は空文字 列です。 (例)YOURMEMBERID[D][E] (例)YOURMEMBERID[D]2[E] ・SESSIONS パケット(クライアント→サーバの同名パケットもありますので注意) SESSIONS[D]セッション総数[D]セッションID[D]人数[D]ユーザ番号[D]ユーザ名[D]ハンドル[D]情報文字列[E] -------------------------------- 人数分繰り返し ------------------------------------------------------ セッション数分繰り返し (例) SESSIONS[D]1[D]123[D]2[D]1[D]hoshi@gamera[D]miruku[D]2[D]ushio@koringo[D]etsuko[D][E] クライアントから SESSIONS パケットを送ると、サーバから送られてきます。 現在そのサーバで成立しているセッションの一覧です。 情報文字列には現在誰がログイン中かの情報(サーバ上での whoコマンドの実行結果等)の文字列が 書かれています。情報文字列中の改行は0x0d(CR)です。 サーバの設定によっては情報文字列は空文字列の場合もあります。