DXライブラリで通信で座標のやりとり

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
sadora3
記事: 175
登録日時: 11年前

DXライブラリで通信で座標のやりとり

#1

投稿記事 by sadora3 » 8年前

PC同士をLANケーブルでつないで、対戦ゲームを作りたいです。
それでDXライブラリの通信の関数を使ってまず座標のやり取りをしてみようと試みましたが、出来ませんでした。
何が原因なのでしょうか。
ちなみに対戦ゲーム自体は出来ています。

エラー内容は受信側の、
NetWorkRecv( NetHandle , P , DataLength );
ここでアクセス違反らしいです。

それともう一つ質問がありまして、LANでの通信には「UDPを使用して~」の関数は使いませんよね?
この関数は世界で通信したいときに使うという認識で正しいでしょうか?

OS:Windows7
コンパイラ:VisualStudio2010
言語:C
ライブラリ:DXライブラリ

・送信側

コード:

#include "DxLib.h"

struct PLAYER{
	int X;
	int Y;
} P;

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
             LPSTR lpCmdLine, int nCmdShow )
{
    char StrBuf[ 256 ] ;    // データバッファ
    IPDATA Ip ;        // 接続用IPアドレスデータ
    int NetHandle ;        // ネットワークハンドル
    int DataLength ;        // 受信データ量保存用変数

	ChangeWindowMode(TRUE);
	SetDoubleStartValidFlag( TRUE ) ;
	SetMainWindowText("送信側");

    if( DxLib_Init() == -1 )    // DXライブラリ初期化処理
    {
         return -1;    // エラーが起きたら直ちに終了
    }

    // IPアドレスを設定( ここにある4つのIP値は仮です )
    Ip.d1 = 127 ;
    Ip.d2 = 0 ;
    Ip.d3 = 0   ;
    Ip.d4 = 1 ;

    // 通信を確立
    NetHandle = ConnectNetWork( Ip, 9850 ) ;

	P.X = 10;
	P.Y = 20;

    // 確立が成功した場合のみ中の処理をする
    if( NetHandle != -1 )
    { 
        // データ送信
        NetWorkSend( NetHandle , &P , sizeof(PLAYER) ) ;

        // データがくるのを待つ
        while( !ProcessMessage() )
        {
            // 取得していない受信データ量を得る
            DataLength = GetNetWorkDataLength( NetHandle ) ;

            // 取得してない受信データ量が0じゃない場合はループを抜ける
            if( DataLength != 0 ) break ;
        }

        // データ受信
        NetWorkRecv( NetHandle , StrBuf , DataLength ) ;    // データをバッファに取得

        // 受信したデータを描画
        DrawString( 0 , 0 , StrBuf , GetColor( 255 , 255 , 255 ) ) ;

        // キー入力待ち
        WaitKey() ;

        // 接続を断つ
        CloseNetWork( NetHandle ) ;
    }

    DxLib_End() ;    // DXライブラリ使用の終了処理

    return 0 ;    // ソフトの終了
}
・受信側

コード:

#include "DxLib.h"

struct PLAYER{
	int X;
	int Y;
};

PLAYER *P;

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
            LPSTR lpCmdLine, int nCmdShow )
{
    int NetHandle , LostHandle ;    // ネットワークハンドル
    int DataLength ;            // 受信データ量保存用変数
    IPDATA Ip ;            // 接続先IPアドレスデータ

	ChangeWindowMode(TRUE);
	SetDoubleStartValidFlag( TRUE ) ;
	SetMainWindowText("受信側");


    if( DxLib_Init() == -1 )    // DXライブラリ初期化処理
    {
        return -1;    // エラーが起きたら直ちに終了
    }

    // 接続してくるのを待つ状態にする
    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() )
        {
            // 取得していない受信データ量が0以外のときはループから抜ける
            if( GetNetWorkDataLength( NetHandle ) != 0 ) break ;
        }

        // データ受信
        DataLength = GetNetWorkDataLength( NetHandle ) ;    // データの量を取得
        NetWorkRecv( NetHandle , P , DataLength );    // データをバッファに取得

        // 受信したデータを描画
		DrawFormatString(0,0,0xffffff, "%d", P->X);

        // 受信成功のデータを送信
        NetWorkSend( NetHandle , "繋がったぞ~!!" , 17 ) ;

        // 相手が通信を切断するまで待つ
        while( !ProcessMessage() )
        {
            // 新たに切断されたネットワークハンドルを得る
            LostHandle = GetLostNetWork() ;

            // 切断された接続が今まで通信してた相手だった場合ループを抜ける
            if( LostHandle == NetHandle ) break ;
        }

        // 切断確認表示
        DrawString( 0 , 16 , "切断しました" , GetColor( 255 , 255 , 255 ) ) ;

        // キー入力待ち
        WaitKey() ;
    }

    DxLib_End() ;    // DXライブラリ使用の終了処理

    return 0 ;    // ソフトの終了
}

hide

Re: DXライブラリで通信で座標のやりとり

#2

投稿記事 by hide » 8年前

アクセス違反はポインタ、配列の操作ミスでよく起こります。
受信に使うPの示す先の領域が確保されてないですね。(動作を確認したわけでは無いですが。)
サンプルを少し改造したプログラムのようですが、サンプルそのままでの確認はなさいましたか?
もう一度サンプルコードと並べて、何が違うか確認してください。

UDPと付いている関数での通信は高速な通信が必要な場合に利用します。
ConnectNetWork を利用したものより高速な通信ができると思いますが、
通信内容が届かない可能性などを気にする必要が出てくるはずです。
この辺はネットワークを1日勉強すればわかると思うので、必要であれば調べるとgoodです。

sadora3
記事: 175
登録日時: 11年前

Re: DXライブラリで通信で座標のやりとり

#3

投稿記事 by sadora3 » 8年前

ああ・・・分かりました。
PLAYER P;
NetWorkRecv( NetHandle , &P , DataLength );
こうかくべきだったのですね。
ポインタ変数にはアドレスを格納するべきなのに、実体を格納してしまってたんですかね。

サンプルそのままのはちゃんと動かしてました。

UDPは高速の通信に使うのですね。
リアルタイムで進行するゲームとかですよね。私の対戦ゲームはターン制なので大丈夫そうです。
ネットワークの勉強はちょっとモチベと時間がないので難しそうです・・・。

回答ありがとうございました!

閉鎖

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