ページ 11

DXライブラリ 通信

Posted: 2012年6月13日(水) 22:54
by 01uNLUCKy
DXライブラリを使って、サーバーとクライアントの通信を行うテストプログラムを作りました。
クライアントがサーバーに接続すると、PlDataを送信します。それを、サーバーが受信すると、PlDataに保存します。
保存したPlDAtaの中の、nameと、pl.flagをもとに”待機””準備”を表示します。
その後、ConnectCountを送り、クライアントはNumに保存し、それを表示します。

PlData.pl.flagをもとに”待機””準備”は表示できるのですが、PlData.nameが表示できません。
なぜ、表示できないのかわかりません。
なぜ、表示できないのか、どうすれば表示できるかを教えてください。

サーバーは後々のことを考え、Port.txtから、ポート番号を読み込むようにしてありますが、読み込めない場合9850を使うようになっております。

以下はソースです。
現在、最大同時接続可能人数は4人にしてあります。

コード:

//server.cpp

#include"DxLib.h"

#define PLAYER_MAX

//ネットワーク関係初期化
void NetWork_Init(){

	//ポート番号設定 Portに代入
	int row;
             int Port;

	FILE *fp;
	fp = fopen("Port.txt","r");

	if(fp == NULL){
		exit(1);//ファイルが開けなかった
		Port = 9850;
	}
	else{
		//ファイルが開けた
		fscanf(fp,"%d",&row);
		Port = row;
		
		//ポート番号が無効なら9850代入
		if(Port < 0 || Port > 65535) Port = 9850;

	}

	fclose(fp);


	//接続待機状態 ポートは int Port
	PreparationListenNetWork(Port);

	//ネットハンドル初期化
	for(int i=0; i<PLAYER_MAX; i++){
	    PlData[i].NetHandle = -1;
	}

}

//接続中台数格納変数
int ConnectCount = 0;

//データ受信
void RecvData(){

	int DataLength = 0;

	// データが送られて来るまで待つ
	while( DataLength != 0 )
	{
		DataLength = GetNetWorkDataLength( PlData[ConnectCount].NetHandle ) ;	// データの量を取得
	}

	// データ受信
	NetWorkRecv( PlData[ConnectCount].NetHandle , &PlData[ConnectCount] , DataLength );	// データをバッファに取得

}

	
//新しい接続があればIP取得
void NewConnect(){

	//IP取得
	GetNetWorkIP(PlData[ConnectCount].NetHandle,&PlData[ConnectCount].ip);
	RecvData();
	NetWorkSend(PlData[ConnectCount].NetHandle,&ConnectCount,sizeof(ConnectCount));
	ConnectCount++;

}

//接続待機
void WaitConnect(){

	//接続数がマックスでないなら
	if(ConnectCount < PLAYER_MAX){

    	//新しい接続があればネットワークハンドル取得
    	PlData[ConnectCount].NetHandle = GetNewAcceptNetWork();
    	if(PlData[ConnectCount].NetHandle != -1){
    	    NewConnect();
    	}
	}

}

//データ絵画	
void WaitConnectDraw(){

	//一台以上接続しているなら
	if(ConnectCount > 0){

		//接続している数だけループ
		for(int i=0; i<ConnectCount; i++){

			int Y = 250 + i * 50;
			char str[10];

			DrawFormatString(  70, Y, Cwhite, "Player%d", i + 1);
			DrawFormatString( 205, Y, Cwhite, "%s", PlData[i].name);
			
			switch(PlData[i].pl.flag){
			case 0:
				strcpy(str,"待機");
				break;
				
			case 1:
				strcpy(str,"準備");
				break;

			default:
				strcpy(str,"エラー");
				break;

			}

			DrawFormatString( 320, Y, Cwhite, "%s", str);

		}

	}

	DrawString(  70, 200, "プレイヤー", Cwhite);
	DrawString( 205, 200, "名前", Cwhite);
	DrawString( 320, 200, "状態", Cwhite);

}

//切断処理
void LostConnect(){

	//ロストネットワークハンドル
	int LostHandle;

	for(int i=0; i<ConnectCount; i++){

    	//切断されたネットワークハンドル取得
    	LostHandle = GetLostNetWork();

    	//切断された接続が今まで接続していた相手だったら
	    if(LostHandle == PlData[i].NetHandle){
         
			int num = PlData[i].pl.Num + 1;

			for(int i=0; i<ConnectCount-num; i++)
				memcpy(&PlData[i],&PlData[i + 1],sizeof(PlData[i + 1]));

			ConnectCount--;

		}
		
	}

}
// プログラムは WinMain から始まります
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
						LPSTR lpCmdLine, int nCmdShow )
{

	ChangeWindowMode(TRUE);//ウィンドウモード
	SetGraphMode(640,480,16);//絵画モード初期化

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

	SetDrawScreen(DX_SCREEN_BACK);
	
	NetWork_Init();//ネット関係初期化

	//メインループ 
    while(!ProcessMessage()){
		ClearDrawScreen();

		WaitConnect();

		LostConnect();

		WaitConnectDraw();

                 ScreenFlip();
    }


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

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

コード:

//cliant.cpp

#include "DxLib.h"

typedef struct{
	int x,y;
	int floor;
	int Num;
	int count;
	int flag;
}Player_t;


typedef struct{
	Player_t pl;
	char name[10];
	int NetHandle;
	IPDATA ip;
}PlayerData_t;

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
			 LPSTR lpCmdLine, int nCmdShow )
{
	int DataLength ;		// 受信データ量保存用変数

	PlayerData_t PlData = {{0,0,0,-1,0,0},"player",0,{127,0,0,1},};

	ChangeWindowMode(TRUE);

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

	// 通信を確立
	PlData.NetHandle = ConnectNetWork( PlData.ip, 9850 ) ;

	// 確立が成功した場合のみ中の処理をする
	if( PlData.NetHandle != -1 )
	{ 
		
		NetWorkSend(PlData.NetHandle,&PlData.ip,sizeof(PlData));

		while( !ProcessMessage() )
		{
			// 取得していない受信データ量を得る
			DataLength = GetNetWorkDataLength( PlData.NetHandle ) ;

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

		// データ受信
		NetWorkRecv( PlData.NetHandle , &PlData.pl.Num , DataLength ) ;	// データをバッファに取得

		DrawFormatString(0,0,GetColor(255,255,255),"%d",PlData.pl.Num);

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

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

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

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


Re: DXライブラリ 通信

Posted: 2012年6月14日(木) 00:13
by h2so5

コード:

NetWorkSend(PlData.NetHandle,&PlData.ip,sizeof(PlData));
IPアドレスしか送信していないのでは?

[追記]
というかこのコードは明らかにバッファオーバーランしていますね...