通信で複数のデータを一気におくりたい

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

通信で複数のデータを一気におくりたい

#1

投稿記事 by sadora3 » 8年前

複数のデータを一気に送信して、それを受信するプログラムを書きたいです。
以下のようなプログラムを組んでみたのですが、turnの値だけ変わりません。
原因はなんでしょうか?

それに受信側のプログラムを閉じたときによくわからないエラーが出てきます。
Run-Time-Check Failuer#2
これは一体なんでしょうか?

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

・送信側

コード:

#include"DxLib.h"

struct PLAYER{
	int X;
	int Y;
};

PLAYER P[2];

int ProcessLoop(){
	if(ProcessMessage() != 0){  return 0;  }
	if(ClearDrawScreen() != 0){ return 0;  }
	return 1;
}

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int){
	SetOutApplicationLogValidFlag(FALSE);
	ChangeWindowMode(TRUE);
	SetDoubleStartValidFlag( TRUE ) ;
	SetMainWindowText("送信側");
	SetGraphMode(640, 480, 16);
	SetBackgroundColor(0, 0, 0);
	if(DxLib_Init() == -1 || SetDrawScreen(DX_SCREEN_BACK) != 0){   return -1;  }

	P[0].X = 1;
	P[0].Y = 2;
	P[1].X = 3;
	P[1].Y = 4;

	IPDATA Ip;
	Ip.d1 = 127;
    Ip.d2 = 0;
    Ip.d3 = 0;
    Ip.d4 = 1;

	int NetHandle;

	NetHandle = ConnectNetWork(Ip, 9850);

	int Flag = false;
	int turn = 0;

	while(ProcessLoop() && !CheckHitKey(KEY_INPUT_ESCAPE)){
		DrawFormatString(0,0,0xffffff, "Sキーでデータを送信します");
		if(CheckHitKey(KEY_INPUT_S)){
			NetWorkSend(NetHandle , &P[0], sizeof(PLAYER));
			NetWorkSend(NetHandle , &P[1], sizeof(PLAYER));
			NetWorkSend(NetHandle , &turn, sizeof(int));
			break;
		}
		
		ScreenFlip();
	}
	CloseNetWork(NetHandle);
	DxLib_End();
	return  0;
}
・受信側

コード:

#include"DxLib.h"

struct PLAYER{
	int X;
	int Y;
};

int ProcessLoop(){
	if(ProcessMessage() != 0){  return 0;  }
	if(ClearDrawScreen() != 0){ return 0;  }
	return 1;
}

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int){
	SetOutApplicationLogValidFlag(FALSE);
	ChangeWindowMode(TRUE);
	SetDoubleStartValidFlag( TRUE ) ;
	SetMainWindowText("受信側");
	SetGraphMode(640, 480, 16);
	SetBackgroundColor(0, 0, 0);
	if(DxLib_Init() == -1 || SetDrawScreen(DX_SCREEN_BACK) != 0){   return -1;  }

	PLAYER P[2] = {9,9,9,9};
	int NetHandle = -1;
	int DataLength ;
	int turn = 9;

	PreparationListenNetWork(9850);

	while(ProcessLoop() && !CheckHitKey(KEY_INPUT_ESCAPE)){
		if(NetHandle == -1){
			DrawFormatString(0,0,0xffffff, "接続待ちです");
			NetHandle = GetNewAcceptNetWork();
		}

		if(NetHandle != -1){
			DataLength = GetNetWorkDataLength(NetHandle);
			NetWorkRecv(NetHandle, &P[0], DataLength);

			DataLength = GetNetWorkDataLength(NetHandle);
			NetWorkRecv(NetHandle, &P[1], DataLength);

			DataLength = GetNetWorkDataLength(NetHandle);
			NetWorkRecv(NetHandle, &turn, DataLength);

			DrawFormatString(0,0,0xffffff, "%d", P[0].X);
			DrawFormatString(0,20,0xffffff, "%d", P[0].Y);
			DrawFormatString(0,40,0xffffff, "%d", P[1].X);
			DrawFormatString(0,60,0xffffff, "%d", P[1].Y);
			DrawFormatString(0,80,0xffffff, "%d", turn);
		}
		ScreenFlip();
	}

	DxLib_End();
	return  0;
}


アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: 通信で複数のデータを一気におくりたい

#2

投稿記事 by みけCAT » 8年前

とりあえず、&P[0]に対しDataLengthバイト読みこませようとしてはいけません。
もしDataLengthがsizeof(P)より大きいと、範囲外へのアクセスを起こしてしまいます。
また、DataLengthがsizeof(P[0])より大きかった場合も、turnに格納するべきデータまで消してしまう可能性があります。
他のNetWorkRecvも同様に危険です。
NetWorkRecvの第三引数に何も考えずDataLengthを入れるのではなく、受信したいデータのサイズに合った適切な値を渡してください。
GetNetWorkDataLengthは届いているデータサイズが受信したいデータのサイズ以上であることを確認し、データが足りなかったら待機するのに用いるとよいでしょう。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

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

Re: 通信で複数のデータを一気におくりたい

#3

投稿記事 by sadora3 » 8年前

以下のようなプログラムになりました。
サイズは直接指定してよかったのですね。
ありがとうございました。

コード:

#include"DxLib.h"
 
struct PLAYER{
    int X;
    int Y;
};
 
int ProcessLoop(){
    if(ProcessMessage() != 0){  return 0;  }
    if(ClearDrawScreen() != 0){ return 0;  }
    return 1;
}

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int){
    SetOutApplicationLogValidFlag(FALSE);
    ChangeWindowMode(TRUE);
    SetDoubleStartValidFlag( TRUE ) ;
    SetMainWindowText("受信側");
    SetGraphMode(640, 480, 16);
    SetBackgroundColor(0, 0, 0);
    if(DxLib_Init() == -1 || SetDrawScreen(DX_SCREEN_BACK) != 0){   return -1;  }
 
    PLAYER P[2] = {9,9,9,9};
    int NetHandle = -1;
    int DataLength ;
    int turn = 9;
 
    PreparationListenNetWork(9850);
 
    while(ProcessLoop() && !CheckHitKey(KEY_INPUT_ESCAPE)){
        if(NetHandle == -1){
            DrawFormatString(0,0,0xffffff, "接続待ちです");
            NetHandle = GetNewAcceptNetWork();
        }
 
        if(NetHandle != -1){
            NetWorkRecv(NetHandle, &P[0], sizeof(PLAYER));
            NetWorkRecv(NetHandle, &P[1], sizeof(PLAYER));
            NetWorkRecv(NetHandle, &turn, sizeof(int));
 
            DrawFormatString(0,0,0xffffff, "%d", P[0].X);
            DrawFormatString(0,20,0xffffff, "%d", P[0].Y);
            DrawFormatString(0,40,0xffffff, "%d", P[1].X);
            DrawFormatString(0,60,0xffffff, "%d", P[1].Y);
            DrawFormatString(0,80,0xffffff, "%d", turn);
        }
        ScreenFlip();
    }
 
    DxLib_End();
    return  0;
}

閉鎖

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