DXライブラリのネットワークで複数種類の変数を受け渡したい

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

DXライブラリのネットワークで複数種類の変数を受け渡したい

#1

投稿記事 by アグルス » 12年前

DXライブラリ標準付属のネットワーク機能で、1対1でチャット機能とゲーム上の操作などの複数の変数をやりとりしたいと考えています。
サンプルをいじって、簡素に1対1の通信に複数のネットハンドルを確立するようにしてみましたが、やはりといってはあれですが、うまく動きませんでした。
Q、W、Eを押したときに100,100に表示されるnet_Handle_がQの場合に256になるなどありえない状態になっています。
私の想定している動きとしては、そもそも一桁の数字しかやりとりしておらず、またQ、W、Eを押したときはnet_Handle_に数字が受け渡されることはないということです。

コード:

(コードは一番下に載せます)

そこで質問なのですが、
①一対の通信に複数のネットハンドルを確立することは可能なのでしょうか。
②できないのであれば、例えばチャットとゲーム操作を分けて送信する場合に最善の方法は何でしょうか。
(私が思いつくのは、状況によって送信・受信する関数を入れ替える方法ですが、少々煩雑そうです。チャットがないのであれば送信した変数の数字で判断できそうですが…)

を知りたいです。回答いただければ嬉しいです。
プログラミングのレベルは苦Cを読み終えた程度です。

コード:

//クライアント側処理//
void Network_Connect_Surver(int &ip_a, int &ip_b, int &ip_c, int &ip_d, int &i_port)
{
	int *str_Buf , *str_Bufb;
	int str_Buf_ , str_Bufb_;
	str_Buf = &str_Buf_;
	str_Bufb = &str_Bufb_;
	IPDATA c_Ip;
	int port;
	int net_Handle , net_Handleb;
	int data_Length , data_Lengthb;
	//IPアドレス設定//
	c_Ip.d1=ip_a;
	c_Ip.d2=ip_b;
	c_Ip.d3=ip_c;
	c_Ip.d4=ip_d;
	port = i_port;
	int *address_test_Ip;	//test_Ipを指し示すポインタ
	int *address_test_Ip_;	//test_Ip_bを指し示すポインタ
	address_test_Ip = &test_Ip;
	address_test_Ip_ = &test_Ip_b;
	DrawFormatString(100,100,color_White,"通信待機中");

	net_Handle = ConnectNetWork(c_Ip,port);	//通信を確立
	net_Handleb= ConnectNetWork(c_Ip,port);
	if(net_Handle!=-1)
	{
		while(ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 && Key_Flame()==0 &&Test_Ip()==0){
			NetWorkSend(net_Handle,address_test_Ip,5);
			NetWorkSend(net_Handleb,address_test_Ip_,5);

			//データが来るまでループ
			while(!ProcessMessage())
			{
				data_Length=GetNetWorkDataLength(net_Handle);
				data_Lengthb=GetNetWorkDataLength(net_Handleb);
				if(data_Length!=0)break;
				if(data_Lengthb!=0)break;
			}
			NetWorkRecv(net_Handle,str_Buf,data_Length);
			NetWorkRecv(net_Handleb,str_Bufb,data_Lengthb);
			DrawFormatString(0,0,color_White,"%d",str_Buf_);
			DrawFormatString(100,100,color_White,"%d",str_Bufb_);
		}
	}
}

//ホスト側処理//
void Network_Wait_Surver(int &i_port)
{
	int *str_Buf , *str_Bufb;
	int str_Buf_ , str_Bufb_;
	str_Buf = &str_Buf_;
	str_Bufb = &str_Bufb_;
	IPDATA c_Ip,c_Ip_;		//通信先IPアドレスデータ
	int net_Handle , net_Handleb;
	int data_Length , data_Lengthb;
	int port=i_port;
	int *address_test_Ip;	//test_Ipを指し示すポインタ
	int *address_test_Ip_;	//test_Ip_bを指し示すポインタ
	address_test_Ip = &test_Ip;
	address_test_Ip_ = &test_Ip_b;

	PreparationListenNetWork(port);
	net_Handle=-1;
	while(!ProcessMessage() && CheckHitKey(KEY_INPUT_ESCAPE)==0 &&ScreenFlip()==0)
	{
		DrawFormatString(100,100,color_White,"通信待機中");
		net_Handle=GetNewAcceptNetWork();
		net_Handleb=GetNewAcceptNetWork();
		if(net_Handle!=-1)break;
	}
	if(net_Handle !=-1)
	{
		StopListenNetWork();
		GetNetWorkIP(net_Handle,&c_Ip);
		GetNetWorkIP(net_Handleb,&c_Ip_);
		while(ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 && Key_Flame()==0 &&Test_Ip()==0 )
		{
			NetWorkSend(net_Handle,address_test_Ip,5);
			NetWorkSend(net_Handleb,address_test_Ip_,5);
			while(!ProcessMessage())
			{
				if(GetNetWorkDataLength(net_Handle)!=0)break;
				if(GetNetWorkDataLength(net_Handleb)!=0)break;
			}
			data_Length=GetNetWorkDataLength(net_Handle);
			data_Lengthb=GetNetWorkDataLength(net_Handleb);
			NetWorkRecv(net_Handle,str_Buf,data_Length);
			NetWorkRecv(net_Handleb,str_Bufb,data_Lengthb);
			DrawFormatString(0,0,color_White,"%d",str_Buf_);
			DrawFormatString(100,100,color_White,"%d",str_Bufb_);
		}
	}
}

//送信する値をキー入力で決定する関数//
int Test_Ip(){
	if(CheckHitKey(KEY_INPUT_Q)==1)
	{test_Ip=1;}
	if(CheckHitKey(KEY_INPUT_W)==1)
	{test_Ip=2;}
	if(CheckHitKey(KEY_INPUT_E)==1)
	{test_Ip=3;}
	if(CheckHitKey(KEY_INPUT_M)==1)
	{test_Ip_b=4;}
	if(CheckHitKey(KEY_INPUT_N)==1)
	{test_Ip_b=5;}
	if(CheckHitKey(KEY_INPUT_B)==1)
	{test_Ip_b=6;}


	return 0;

}


アバター
h2so5
副管理人
記事: 2212
登録日時: 15年前
住所: 東京
連絡を取る:

Re: DXライブラリのネットワークで複数種類の変数を受け渡したい

#2

投稿記事 by h2so5 » 12年前

まずポインタの理解が怪しいような気がします。

コード:

NetWorkSend(net_Handle,address_test_Ip,5);
NetWorkSend(net_Handleb,address_test_Ip_,5);
このコードで何を送信しようとしているのでしょうか? 5という数字はどこから導き出されたのでしょう。

① 一対の通信に複数のネットハンドルを確立することは可能なのでしょうか。
可能です。ホスト側の処理を考えると別々のポートを使用したほうが作りやすかもしれません。
このコードだとConnectNetWorkとGetNewAcceptNetWorkの順番がホストとクライアント側で一致する保証があるのか怪しい所ですが。

② できないのであれば、例えばチャットとゲーム操作を分けて送信する場合に最善の方法は何でしょうか。
本当にチャットとゲーム操作を分けて送信する必要があるのかをまず検討するべきだと思います。
送信するデータの先頭に何らかのフラグを付ければ、受信側でチャットとゲーム操作を振り分けることは難しくないです。
チャットとゲーム操作のデータの量や送信頻度に差がある場合は、分けないとデバッグや最適化が難しくなる可能性があります。

アグルス

Re: DXライブラリのネットワークで複数種類の変数を受け渡したい

#3

投稿記事 by アグルス » 12年前

>h2so5さん
返信ありがとうございます。
送信しようと試みていたのは、test_Ip関数で得たtest_Ip変数の内容です。
あと、5という数字はあまり意味がなく、前回まで5桁の数字でテストしていた名残です。


やっぱりポートなどは変更したほうが作りやすいのですね。
あとこのコードだと接続と接続待ちうけの順番が食い違ってしまったりしますかね……。
ひとつひとつif文などで接続を確認して次の接続を行えば大丈夫そうでしょうか?


送信する変数を配列にし、頭に数字を設定して……といった感じで行えばいいでしょうか。
そうすれば分けて処理しなくても大丈夫そうですね。
簡単そうなので、この方法を使用してみたいと思っています。
自宅に戻って、この方法でいけそうであれば解決モードにしますね。
回答ありがとうございました。

アグルス

Re: DXライブラリのネットワークで複数種類の変数を受け渡したい

#4

投稿記事 by アグルス » 12年前

忙しくてプログラミングする時間が無く報告ができませんでした、すいません

自分なりに変えてみたのですが、今度はバッファオーバーフローや強制終了エラーが頻発するようになってしまいました。

構造としては、1ループ毎にお互いはグローバル変数char test_Ip_X[64]の内容を相手に送信し、
受信した側はstr_Buf[0]の値を見て1であれば座標0,0に受信した値を表示、その他であれば座標100,100に受信した値を表示
といったプログラムです。
test_Ip_X[64]の中身は押したボタンにより数値が異なるようになっています

(他に地味なところでは、クライアントは2回net_Handle = ConnectNetWork(connect_Ip,i_port);を実行しなければ接続できないです。
これを2つ連続で使うと上手く接続できますが、何かスマートな書き方はないでしょうか。)

改善方法指南いただければ幸いです。

ホスト

コード:

//ホスト側処理
void Network_Wait_Surver(int &i_port)
{
	char str_Buf[256];					//データバッファ
	int net_Handle, lost_Handle;		//ネットワークハンドル
	int surver_Port;
	surver_Port = i_port;
	int data_Length;					//受信データ量保存用変数
	IPDATA mukouno_Ip;					//接続先IPデータ
	int sub=0;

	PreparationListenNetWork(i_port);

	net_Handle =-1;
	while(ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 && Key_Flame()==0)
	{
		net_Handle = GetNewAcceptNetWork();						//接続があったならそのネットワークハンドルを得る
		if(net_Handle != -1)break;								//接続が確認されたならばbreak
	}
	if(net_Handle !=-1)											//接続されているならば
	{
		StopListenNetWork();									//これ以上の接続を止める
		GetNetWorkIP(net_Handle,&mukouno_Ip);					//相手方のIPを得る
		while(Test_Ip()==0 && ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 && Key_Flame()==0)
		{
			DrawString(0,0,str_Buf,GetColor(255,255,255));
			if(str_Buf[0]=='1')
			{
			DrawString(0,0,str_Buf,GetColor(255,255,255));		//str_Buf描写
			}
			else
			{
				DrawString(100,100,str_Buf,GetColor(255,255,255));
			}
			NetWorkSend(net_Handle,test_Ip_X,64);
			if(GetNetWorkDataLength(net_Handle)!=0)				//取得していない受信データ量が0以外のときは
			{
				data_Length=GetNetWorkDataLength(net_Handle);	//データの量を取得
				NetWorkRecv(net_Handle,str_Buf,data_Length);	//データをバッファに取得
			}

			

		}
	}


}
クライアント

コード:

//クライアント側処理
void Network_Connect_Surver(int &ip_a, int &ip_b, int &ip_c, int &ip_d, int &i_port)
{
	char str_Buf[256];
	IPDATA connect_Ip;
	int surver_Port,lost_Handle;
	connect_Ip.d1 = ip_a;
	connect_Ip.d2 = ip_b;
	connect_Ip.d3 = ip_c;
	connect_Ip.d4 = ip_d;
	surver_Port = i_port;
	int net_Handle;
	int data_Length;

	net_Handle = ConnectNetWork(connect_Ip,i_port);				//通信を確立

	if(net_Handle !=-1)											//通信が確立したら
	{
		while(Test_Ip()==0 && ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 && Key_Flame()==0)
		{
			Test_Ip();
			DrawString(0,0,str_Buf,GetColor(255,255,255));
			DrawString(0,0,str_Buf,GetColor(255,255,255));		//str_Bufを表示
			if(str_Buf[0]=='1')
			{
			DrawString(0,0,str_Buf,GetColor(255,255,255));		//str_Buf描写
			}
			else
			{
				DrawString(100,100,str_Buf,GetColor(255,255,255));
			}
			//テストケースここまで
			data_Length = GetNetWorkDataLength(net_Handle);		//取得していない受信データ量を得る

			NetWorkSend(net_Handle,test_Ip_X,64);	//データ送信

			if(data_Length!=0)									//取得していない受信データ量が0でない場合は
			{
				NetWorkRecv(net_Handle,str_Buf,data_Length);	//データを受信する
			}
		}
	}

}
ループしている関数
(Key_Flame()はこのサイトにあるgpupdatekey()関数とほぼ同じです)

コード:

int Test_Ip(){
	if(CheckHitKey(KEY_INPUT_Q)==1)
	{
		test_Ip_X[0]='1';
		test_Ip_X[1]='A';
	}
	if(CheckHitKey(KEY_INPUT_W)==1)
	{
		test_Ip_X[0]='1';
		test_Ip_X[1]='B';
	}
	if(CheckHitKey(KEY_INPUT_E)==1)
	{test_Ip_X[0]='1';
	test_Ip_X[1]='C';}
	if(CheckHitKey(KEY_INPUT_M)==1)
	{
		test_Ip_X[0]='2';
		test_Ip_X[1]='4';
	}
	if(CheckHitKey(KEY_INPUT_N)==1)
	{
		test_Ip_X[0]='2';
		test_Ip_X[1]='5';
	}
	if(CheckHitKey(KEY_INPUT_B)==1)
	{	test_Ip_X[0]='2';
		test_Ip_X[1]='6';
	}


	return 0;

}

アバター
h2so5
副管理人
記事: 2212
登録日時: 15年前
住所: 東京
連絡を取る:

Re: DXライブラリのネットワークで複数種類の変数を受け渡したい

#5

投稿記事 by h2so5 » 12年前

DrawStringに初期化してないバッファを渡していたりとか、ポインタや文字列に関する理解ができていないと思うので先にそちらを勉強してください。
ネットワークプログラミングに挑戦するのはまだ早いとおもいます。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: DXライブラリのネットワークで複数種類の変数を受け渡したい

#6

投稿記事 by softya(ソフト屋) » 12年前

h2so5さんの言われる通り、ポインタの知識が必須で例えば同一PC内でバイナリファイルで別プログラム間でデータの受け渡しが出来る様な技術力がないと困難です。まず、そちらを出来るように頑張ってみて下さい。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アグルス

Re: DXライブラリのネットワークで複数種類の変数を受け渡したい

#7

投稿記事 by アグルス » 12年前

h2so5さん、softyaさん返信ありがとうございます。
まずそちらを勉強したいと思います。
そこで躓くことがあればよければまた質問させてください。

とりあえずこのスレッドは解決にしておきますね

閉鎖

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