「なでしこ」バグ&要望掲示板

なでしこのバグや実現して欲しい機能の要望を行う掲示板です。
[一覧へ] > (@888) [低] [感謝]
@888■ (#2814) TCPで送信したデータがよく欠損する? - とけい (2017-09-21 20:11) /低 詳細求む!
【症状】TCPで送信したデータがよく欠損する
【バージョン】1.562  windows10

ゲームに通信対戦モードをつけました。
nakonet.nakoを取込し、TCPサーバー、TCPクライアントを使用しています。
(サーバーとはTCPサーバー。クライアントとはTCPクライアント)

送信データは主にBASE64の文字列です。
ゲームはターン制で、ターン終了時に行動をまとめてBASE64にして送ります。
1回で1000字~2000字くらいになります。


これが、けっこうな確率で欠損して届きます。


データが途中で切れているようで、後半部分がなくなっています。
データによる再現性はなく、同じデータを再度送ってもらうと欠損なしで届くこともあります。

受け取ったデータをBASE64デコードしたものをログに残しているのですが、1055文字目の一定文字数で切れていました。
BASE64デコード前は1.3倍くらいの1440バイトほどだと思われます。
ちょうどパケット分割がどうとかいうサイズ(知識は聞きかじり)らへんだと思います。


なでしこの更新履歴に「2016/09/08 version 1.562
 -- nakonet.dllのライブラリIndy10を最新版に更新。」とありますが
nakonet.dllに問題はないでしょうか。

それとも手探りでプログラムした受信データの処理がよくないのでしょうか。
それともTCPでの送受信ってこういうものなんでしょうか。


送受信部分のプログラムはおおむね下記のような雰囲気です。

#-----------------------------------------------------------------------
//BASE64エンコードして開始と終端記号をつける
●送信(txt)
 base64とは変数
 base64 = txtをBASE64エンコード
 base64 = 「<{base64}>」
 base64をクライアントで送信

サーバーの受信した時は~サーバーの受信データをサーバーで全送信

受信データとは変数
クライアントの受信した時は~
 受信データ=受信データ & (クライアントで受信) //ためておく

//ゲームループから呼び出す(秒間20回ほど)
●受信処理
 dataとは変数
 data = 受信データ
 受信データ=「」//ローカル変数に移して速やかに消す
 
 base64とは変数
 txtとは変数
 (data<>「」)でループ
   base64 = dataの「<」から「>」まで範囲切り取る
   //「>」がない場合、最後まで切り取る。
   //欠損している場合、「>」がない
   txt=base64をBASE64デコード
   //txtを見てゲームに反映

#-----------------------------------------------------------------------

(#2815) TCP通信の基本 - うぇいく (2017-09-21 21:53) /低 詳細求む!
送信する塊の括りで受信するわけではないため、常にバッファに追加書きで貯め込みながら、開始記号と終了記号がそろうごとに、そろった範囲のみを処理をする必要があります。
・開始ししか受信してない。
・前回開始受信済みで今回も終了は無い(途中しかない)
・開始と終了が複数セットまとまって受信する
・前回開始を受信していて、今回は終了と開始を受信して、2つ目の終了はない。
・1バイトづ受信する
といういろいろな可能性があります。
順序は保障されますが、送信した単位という概念はありません。なので、受信処理内でクリアしてよいのは、最後に開始とペアになった終端記号までで、それ以降は残して次で使う必要があります。そのため、受信処理内でローカル変数にコピーせずに、先頭から切り取りながら処理した方が良いと思います(後から戻そうともうと、受信イベントでの追加とコンフリクトする可能性が。
※開始記号や終端記号そのものを複数バイトにした場合、それらが分かれて受信する可能性もあり、より複雑になります。


(#2816) 「受信した時」の発生タイミング - とけい (2017-09-21 23:04) /低 感謝
2000バイト送ったら2000バイト届いてから「クライアントの受信した時」が発生すると思ってたんですが違うんですね。
受信データに終端記号があったらそこまで切り取る、なければ残して次のデータを追加、の方法でやってみます。

ありがとうございました。

(#2814)へ返信する:

名前
タイトル
本文
優先度
状態
確認キー お手数ですが、いたずら防止のために、「真夏」の読み方を記入してください。
編集キー 編集時に使うキーを入力(省略可能)
添付ファイル 画像ファイル(最大300KB)を添付可能