トップページ > 過去ログ > 記事閲覧
ネットワーク通信について
名前:かち割氷 日時: 2011/07/14 17:18

ネットワークを用いて、映像の同期をとりたいと考えています。 サンプルプログラムを参考に1対1での通信は出来たのですが、通信速度の関係か、クライアントとサーバーの動きが多少ずれてしまいます。 UDPを用いれば信頼性は低くても速度は出るということで、現在UDPでの設計も視野に入れています。 クライアント側だけでも同期がとれていればいいのですが、6台のPC相手にサーバーから同じ値を同時に送り、6台の映像の動きを完全に同期させることは可能でしょうか? アドバイスを頂ければ幸いです。 色々試している途中で、ソースが汚かったり、改行などが雑になっていて見づらいかもしれませんが、現在のソースも載せておきます。 /////////////////////現在のソースです///////////////////////// #include "DxLib.h" #include "main.h" #include <stdio.h> #define DATA "sample.txt" int NetHandle ; // ネットワークハンドル int NetWorkConnect(char *mode); int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { char mode[256]; int FileHandle; int c_state; int LostHandle ; int DataLength2 ; char senddata[256]; int count=0; int j=1; int ModelHandle ; float z= 500.0f; ChangeWindowMode(1); SetDoubleStartValidFlag( TRUE ) ; SetAlwaysRunFlag(TRUE); if( DxLib_Init() == -1 ) // DXライブラリ初期化処理 { return -1; // エラーが起きたら直ちに終了 } ModelHandle = MV1LoadModel( "sample.x" ) ; SetCameraPositionAndAngle( VGet( 0.0f, 0.0f, 0.0f), 0.0f, 0.0f, 0.0f ); SetCameraNearFar( 1.0f, 2000.0f ) ; FileHandle=FileRead_open(DATA) ; if(FileRead_gets(mode,256,FileHandle)==-1){ } else{ c_state = NetWorkConnect(mode); } DrawString( 0 , 16 , "接続中" , GetColor( 255 , 255 , 255 ) ) ; WaitTimer(1000); if(c_state == 1){ while( ProcessMessage()==0 && ClearDrawScreen()==0 && CheckHitKey( KEY_INPUT_ESCAPE )!=1){ if( CheckHitKey( KEY_INPUT_W )==1){ z= z + 0.1f; j=1; } if( CheckHitKey( KEY_INPUT_S )==1){ z= z - 0.1f; j=1; } sprintf(senddata,"%f",z); if(j==1){ NetWorkSend( NetHandle , senddata , lstrlen(senddata)+1 ) ; j=0; } // 画面に映る位置に3Dモデルを移動 MV1SetPosition( ModelHandle, VGet(0.0f, 0.0f ,z ) ) ; // 3DモデルのY軸の回転値をセットする MV1SetRotationXYZ( ModelHandle, VGet( 0.0f,0.0f, 0.0f ) ) ; // 3Dモデルの描画 MV1DrawModel( ModelHandle ) ; WaitTimer( 5 ) ; } } else if(c_state==2){ while( ProcessMessage()==0 && ClearDrawScreen()==0 && CheckHitKey( KEY_INPUT_ESCAPE )!=1){ // 取得していない受信データ量が0以外のときはループから抜ける if( GetNetWorkDataLength( NetHandle ) != 0 ){ // データ受信 DataLength2 = GetNetWorkDataLength( NetHandle ) ; // データの量を取得 // 取得してない受信データ量が0じゃない場合 // データ受信 NetWorkRecv( NetHandle , senddata , DataLength2 ) ; // データをバッファに取得 z=(float)atof(senddata); } // 画面に映る位置に3Dモデルを移動 MV1SetPosition( ModelHandle, VGet(0.0f, 0.0f ,z ) ) ; // 3DモデルのY軸の回転値をセットする MV1SetRotationXYZ( ModelHandle, VGet( 0.0f,0.0f, 0.0f ) ) ; // 3Dモデルの描画 MV1DrawModel( ModelHandle ) ; // 新たに切断されたネットワークハンドルを得る LostHandle = GetLostNetWork() ; // 切断された接続が今まで通信してた相手だった場合ループを抜ける if( LostHandle == NetHandle ) break ; WaitTimer( 5 ) ; } } if(c_state==2){ NetWorkConnect("N_LOST"); } // 接続を断つ if(c_state==1){ NetWorkConnect("N_CLOSE"); } FileRead_close( FileHandle ) ; DxLib_End() ; // DXライブラリ使用の終了処理 return 0 ; // ソフトの終了 } int NetWorkConnect(char *mode){ char StrBuf[ 256 ] ; // データバッファ int DataLength ; // 受信データ量保存用変数 IPDATA Ip ; // 接続先IPアドレスデータ if(strcmp(mode,"CLIANT")==0){ //////-- 接続待ち側プログラム--////// DrawString( 0 , 16 , "クライアントだよ" , GetColor( 255 , 255 , 255 ) ) ; // 接続してくるのを待つ状態にする PreparationListenNetWork( 9850 ) ; // 接続してくるかESCキーが押されるまでループ NetHandle = -1 ; while( !ProcessMessage() && CheckHitKey( KEY_INPUT_ESCAPE ) == 0 ) { // 新しい接続があったらそのネットワークハンドルを得る NetHandle = GetNewAcceptNetWork() ; if( NetHandle != -1 ) break ; } // 接続されていたら次に進む if( NetHandle != -1 ) { // 接続の受付を終了する StopListenNetWork() ; // 接続してきたマシンのIPアドレスを得る GetNetWorkIP( NetHandle , &Ip ) ; // データが送られて来るまで待つ while( !ProcessMessage() ) { // 取得していない受信データ量を得る DataLength = GetNetWorkDataLength( NetHandle ) ; // 取得してない受信データ量が0じゃない場合はループを抜ける if( DataLength != 0 ) break ; } // データ受信 NetWorkRecv( NetHandle , StrBuf , DataLength ); // データをバッファに取得 // 受信したデータを描画 DrawString( 0 , 0 , StrBuf , GetColor( 255 , 255 , 255 ) ) ; // 受信成功のデータを送信 NetWorkSend( NetHandle , "繋がったぞ〜!!" , 17 ) ; return 2; } } else if(strcmp(mode,"SERVER")==0){ //////-- 接続側プログラム--////// DrawString( 0 , 16 , "サーバーだよ" , GetColor( 255 , 255 , 255 ) ) ; // IPアドレスを設定( ここにある4つのIP値は仮です ) Ip.d1 = 100 ; Ip.d2 = 100 ; Ip.d3 = 10 ; Ip.d4 = 10 ; // 通信を確立 NetHandle = ConnectNetWork( Ip, 9850 ) ; // 確立が成功した場合のみ中の処理をする if( NetHandle != -1 ) { // データ送信 NetWorkSend( NetHandle , "繋がったか〜!?" , 17 ) ; // データがくるのを待つ while( !ProcessMessage() ) { // 取得していない受信データ量を得る DataLength = GetNetWorkDataLength( NetHandle ) ; // 取得してない受信データ量が0じゃない場合はループを抜ける if( DataLength != 0 ) break ; } // データ受信 NetWorkRecv( NetHandle , StrBuf , DataLength ) ; // データをバッファに取得 // 受信したデータを描画 DrawString( 0 , 0 , StrBuf , GetColor( 255 , 255 , 255 ) ) ; return 1; } } if(strcmp(mode,"N_CLOSE")==0){ CloseNetWork( NetHandle ) ; } else if(strcmp(mode,"N_LOST")==0){ // 切断確認表示 DrawString( 0 , 16 , "切断しました" , GetColor( 255 , 255 , 255 ) ) ; } return -1; }

Page: 1 |

Re: ネットワーク通信について ( No.1 )
名前:いっち 日時:2011/07/14 23:05

> 6台のPC相手にサーバーから同じ値を同時に送り、6台の映像の動きを完全に同期させることは可能でしょうか? 環境によるのではないでしょうか?少なくとも私はラグの全く発生しないPC上のオンラインゲームを見たことは無いです。 また、ご提供頂いたソースを1台のPC上で動作させて見ましたが、特に気になるほどのずれ等は見受けられませんでした。 > 色々試している途中で、ソースが汚かったり、改行などが雑になっていて見づらいかもしれませんが、現在のソースも載せておきます。 余談ですが、コーディング中であっても、インデントには気を使うことをお勧めします。 というより、終わってからインデントしてもあまり意味が無いように思います。
Re: ネットワーク通信について ( No.2 )
名前:管理人 日時:2011/07/17 05:17

クライアント側の6台で完全に同期させることは例え LAN でネットワークを組んで UDP で通信していても難しいと思います 試していないので何とも言えないというところはありますが、 全く同じ構成で且つ性能に余裕のあるPCを6台用意して、 その6台のPCを一つのルータに接続、LANケーブルの長さも同じにして、 そして UDP 通信すれば、もしかしたら60分の1秒以内の誤差に抑えることができるかもしれません ただ、「完全に同期している」といえるものにするのは難しいと思います
Re: ネットワーク通信について ( No.3 )
名前:かち割氷(解決) 日時:2011/07/22 12:35

>いっちさん 他人へ渡す時とエラーの時だけインデントを整理していました。 今後はコーディング中も気をつけるようにしたいと思います。 アドバイスありがとうございます。 >管理人様 やはりハードウェアや通信の関係で誤差は少なからずでるのはしょうがないですよね。 映像としての見た目の同期として考えていたのですが、 なるべく誤差が気にならないようなプログラムを組むように考え直してみます。 丁寧な対応ありがとうございました。

Page: 1 |