TCP/IPの同期??

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
daburi

TCP/IPの同期??

#1

投稿記事 by daburi » 16年前

学校の課題なのですが、問題が解決できずに困っています。
どうか助言をお願いします。

作っているのは、2台のパソコンでデータ通信を行うものなのですが、以下のような動作をします。
①パソコンAで3Dマウスの座標データを取得
②TCP/IP通信を使い、パソコンBへ座標データを転送
③パソコンBで送られてきた座標データを元に3Dグラフィックで絵を表示

また、ソースはこのような感じになっています。
<PC_A(送信側)>
main(){
   while(1){
      GetZahyou();   // 座標データを取得
      SendZahyou();  // パソコンBに転送
   }
}

<PC_B(受信側)>
main(){
   CreateThread();   // 座標を受信するスレッドを作成
   while(1){
      Output();      // 3D座標をグラフィックで表示
   }
}
Thread(){
   while(1){
      GetData();     // 送られてきた座標データを受け取る
   }
}
通信、表示も一応動くのですが、動作が不安定でたびたび強制終了してしまいます。
また、受信側の表示は動作がカクカクでスムーズに動いているとはいえません。

思い当たる原因としていろいろ考えてみたのですが、まず、このプログラムでは送る速度と受け取る速度の調節ができていないため、カクカクになってしまうのではないかと考えています。
それ以外にも、動作の確認のためにPrintf文を数箇所に入れているのですが、受信側のPrintf文の数によってうまく動作したり、すぐに強制終了したりしてしまいます。減らせばいいというものではなく、適量のPrintf文があったほうが動作が安定することからPrintfによる割り込みのせいでちょうどよいタイミングになっているのか?などとも予想しています。

お願いしたいことは、
1.動作の同期をとるためにそれぞれのWhileループを1msでループするようにしたいのですが、その方法を教えていただけないでしょうか。
2.また、他の方法でもっと良いもの、あるいは改善した方が良い点があったら指摘していただけないでしょうか。
以上の二つです。
どうかよろしくおねがいします。

Mist

Re:TCP/IPの同期??

#2

投稿記事 by Mist » 16年前

情報がなさ過ぎて答えづらいですがいくつか気になった点を。
1.サーバ側の表示スレッドと受信スレッド間のデータの受け渡しはきちんと排他制御できていますか?
  両方のスレッドから同じ共有変数に対してアクセスすると強制終了してしまう場合もありますが。
2.動的エリアの取得・解放はきちんと整理できていますか?
  例えば取得と解放を異なるタイミングで行っていて、受信等の処理タイミングによっては取得前に解放を実行してしまう場合があるとか

printfを多くすると発生しなくなるということは、両スレッドが活発に動くと発生するということだろうからスレッド間の排他制御か同期処理でバグってるのだと予想します。

> 1について
「フレームレートの固定」というようなキーワードでググってください。

daburi

Re:TCP/IPの同期??

#3

投稿記事 by daburi » 16年前

Mistさんありがとうございます。
排他制御はミューテックスを使っていたのですが、使った方が強制終了しやすくなってしまったので、コメントアウトしてしまいました。
受信側のメインとスレッドのそれぞれのループでグローバル変数に代入する前後でやってみたのですがうまくいきませんでした。
2の動的エリアの確保と開放ですが、ちょっと意味がよくわからないのですが、特に動的な確保や開放は行っていないと思います。
「フレームレートの固定」も調べてみます。ありがとうございました。

Mist

Re:TCP/IPの同期??

#4

投稿記事 by Mist » 16年前

> 使った方が強制終了しやすくなってしまったので
排他制御でデッドロックしているんじゃないですか?

Mist

Re:TCP/IPの同期??

#5

投稿記事 by Mist » 16年前

ソースがないのですでにそうなっているのかもしれませんが

> グローバル変数に代入する前後
排他制御はスレッド間で共有するグローバル変数にアクセス(リード・ライト両方)する部分に全て行わなければなりません。
ライト(代入)する時だけの排他制御は意味がありません。

daburi

Re:TCP/IPの同期??

#6

投稿記事 by daburi » 16年前

Mistさんなんどもありがとうございます。
変数はひとつしか使っていないのでデッドロックにはなっていないと思います。
排他制御もリード、ライトの両方にかけています。

今日調べてみたところ、どうも受信した値がときどきおかしな値になっていることがあり、それが原因で強制終了しているようでした。recvの間隔が早すぎると受信しきれないことがあるのでしょうか?
それについて受信した値がずれる原因を探してみようと思っています。

Mist

Re:TCP/IPの同期??

#7

投稿記事 by Mist » 16年前

> recvの間隔が早すぎると受信しきれないことがあるのでしょうか?

間隔というのがどれぐらいの時間でどのぐらいのデータを送っているのか判りませんが、極端に短い時間(msecオーダー)の場合、必ず相手に届くと思うのは間違いです。
これはPCの性能とかプログラムのつくりとかの問題ではなくTCPの仕様です。
送信側が1msecごとに1バイトのデータを送信しているからといって、受信側が1msecごとにrecvを行ったとしても1バイトずつ受信できる保証はありません。
少し遅れたり、時には数バイトまとめて受信する場合もあります。
この辺勘違いされていませんでしょうか?

daburi

Re:TCP/IPの同期??

#8

投稿記事 by daburi » 16年前

Mistさんの言うとおり、送ったのと同じだけ受け取れると思っていたのが原因のようでした。
送られてきた値が期待する値であるかをチェックするようにしたら正しく動くようになりました。
どうもありがとうございました。とても助かりました。

閉鎖

“C言語何でも質問掲示板” へ戻る