DxLibリファレンスの通信のプログラムを発展させたい

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

DxLibリファレンスの通信のプログラムを発展させたい

#1

投稿記事 by わからんこ » 13年前

コード:

#include "GV.h"

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
			LPSTR lpCmdLine, int nCmdShow )
{
	ChangeWindowMode(TRUE);
	SetMainWindowText( "サーバー" ) ;

	char StrBuf[MAX_CONNECT_NUM][ 256 ] ;		// データバッファ

	int NetHandle[MAX_CONNECT_NUM],LostHandle[MAX_CONNECT_NUM];	// ネットワークハンドル
	
	int DataLength[MAX_CONNECT_NUM]; ;			// 受信データ量保存用変数
	
	IPDATA Ip[MAX_CONNECT_NUM] ;			// 接続先IPアドレスデータ

	int Num,Flag;

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

	// 接続してくるのを待つ状態にする
	PreparationListenNetWork( 10000 ) ;
	
	
	//初期化
	for(int i=0;i<MAX_CONNECT_NUM;i++){
		strcpy(  StrBuf[i], "" ) ;
		NetHandle[i] = -1 ;
	}
	//ESCキーが押されるまでループ
	while( !ProcessMessage() && CheckHitKey( KEY_INPUT_ESCAPE ) == 0 &&ClearDrawScreen()==0)
	{
		//接続が切れてるかチェック
		for(int i=0;i<MAX_CONNECT_NUM;i++){
			LostHandle[i]=GetLostNetWork();
		if(LostHandle[i]==NetHandle[i])NetHandle[i]=-1;
		}

		//配列番号を決める
		for(int i=0;i<MAX_CONNECT_NUM;i++){
			if(NetHandle[i]==-1){
				Num=i;
				Flag=0;
				break;
			}else{
				Flag=1;
			}
		}

		//接続人数限界以上じゃなかったらつなげる
		if(Flag != 1)
			NetHandle[Num] = GetNewAcceptNetWork();

		//ip保存
		GetNetWorkIP(NetHandle[Num] , &Ip[Num]) ;

		int y=0;
		//接続者の名前を表示
		for(int i=0;i<MAX_CONNECT_NUM;i++){
			//データを受信してる
			if( GetNetWorkDataLength( NetHandle[i] ) != 0 ){
				// データ受信
				DataLength[i] = GetNetWorkDataLength( NetHandle[i] ) ;	// データの量を取得
				NetWorkRecv( NetHandle[i] , StrBuf[i] , DataLength[i] );	// データをバッファに取得
			}else{

			}
			if(NetHandle[i]!=-1){
			// 受信したデータを描画
				DrawFormatString( 0, y,GetColor( 255 , 255 , 255 ), "接続中 IP:%d.%d.%d.%d  名前:%s "
														,Ip[i].d1,Ip[i].d2,Ip[i].d3,Ip[i].d4 ,StrBuf[i] ) ;
			y+=FONT_SIZE;
			// 受信成功のデータを送信
			NetWorkSend( NetHandle[i] , "接続成功" , 9 ) ;
			}
		}

	}

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

	return 0 ;	// ソフトの終了
}
http://dixq.net/forum/viewtopic.php?f=3&t=10029

自分なりに複数人接続できる事を目指してコードを書いてみましたが

うまくいきません。

PreparationListenNetWorkを使って接続受付中状態で他の処理を行うことはできますか?

またループの度にGetNewAcceptNetWork();を行うのはダメですか?

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

Re: DxLibリファレンスの通信のプログラムを発展させたい

#2

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

たぶん無理だと思います。※あとで調べます。
最近DXライブラリやwinsockでゲームサーバーを書く人が多いのですが、実際の所サーバー運用はどうされる予定でしょうか?

家庭用のPCを使いますか? ・・・ 熱問題や信頼性、電気料金、回線速度、冷房費用、24時間接続など問題は山積みです。
レンタルサーバーを使いますか? ・・・ DXライブラリやwinsockはLinuxやUNIXなので使えません。

まず、ここをクリアされたほうが良いと思います。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

わからんこ

Re: DxLibリファレンスの通信のプログラムを発展させたい

#3

投稿記事 by わからんこ » 13年前

そんな大きなものでなく

友達4人ぐらいと、通信できればいいな、と考えている次第です。

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

Re: DxLibリファレンスの通信のプログラムを発展させたい

#4

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

調べてみました。

>PreparationListenNetWorkを使って接続受付中状態で他の処理を行うことはできますか?

出来ます。

>またループの度にGetNewAcceptNetWork();を行うのはダメですか?

出来ます。

と言うことで出来ますが、複数の同時接続だとスレッド化を考えないとマズイと思いますがDXライブラリの通信がスレッドで利用可能か確認できませんでした。

わからんこ さんが書きました:そんな大きなものでなく
友達4人ぐらいと、通信できればいいな、と考えている次第です。
友だちと遊ぶ時に自宅のPCの一台をサーバー用として開放するなら問題ないと思います。
サーバーを管理できる人がかならずサーバーアプリを起動する必要がありますけど。
ルータのポート開けも必要で、光回線など強力なものが望ましくADSLなど貧弱な回線の持ち主がサーバーに成るのは避けたほうが良いです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

わからんこ

Re: DxLibリファレンスの通信のプログラムを発展させたい

#5

投稿記事 by わからんこ » 13年前

一対一の通信には成功したので、次のステップとして

複数人の通信を勉強しようと考え始めました。

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

Re: DxLibリファレンスの通信のプログラムを発展させたい

#6

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

考えて見ましたがスレッドを使わずに、うまく組んでリアルタイム・アクション系じゃなければ多少遅延しても通信は出来ると思います。
で現状の「うまくいきません」の具体的な内容を教えて下さい。それをどうやって確認したのかテスト手順も必要な情報です。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

わからんこ

Re: DxLibリファレンスの通信のプログラムを発展させたい

#7

投稿記事 by わからんこ » 13年前

ハンドルされていない例外が発生しました。

相手と繋がった後、表示されてとまってしまいます。

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

Re: DxLibリファレンスの通信のプログラムを発展させたい

#8

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

わからんこ さんが書きました:ハンドルされていない例外が発生しました。

相手と繋がった後、表示されてとまってしまいます。
サーバーとクライアントのどちらが停止しますか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

わからんこ

Re: DxLibリファレンスの通信のプログラムを発展させたい

#9

投稿記事 by わからんこ » 13年前

一対一の通信は友達にプログラムを渡し起動してもらい

通信を行いテストしてみました。

今回の複数人のテスト方法は同じパソコン内でサーバー側、クライアント側、起動して実験していますが、

サーバー側がとまってしまいます。

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

Re: DxLibリファレンスの通信のプログラムを発展させたい

#10

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

デバッグ開始(F5)で起動すれば問題のあるところで止まると思います。
何処の命令でしょうか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

わからんこ

Re: DxLibリファレンスの通信のプログラムを発展させたい

#11

投稿記事 by わからんこ » 13年前

すいません。クライアント側でした。

Client.exe の 0xda9000f7 でハンドルされていない例外が発生しました: 0xC0000005: Access violation

わからんこ

Re: DxLibリファレンスの通信のプログラムを発展させたい

#12

投稿記事 by わからんこ » 13年前

コード:

#include "DxLib.h"

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

	//ウィンドウに切り替えと多重起動の許可
	SetDoubleStartValidFlag( TRUE ) ;
	ChangeWindowMode(TRUE);
	SetMainWindowText( "クライアント" ) ;

	if( DxLib_Init() == -1 )	// DXライブラリ初期化処理
	{
		 return -1;	// エラーが起きたら直ちに終了
	}
	while( !ProcessMessage()){
	// IPアドレスを設定( ここにある4つのIP値は仮です )
	Ip.d1 = 192 ;
	Ip.d2 = 168 ;
	Ip.d3 = 11   ;
	Ip.d4 = 50 ;

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

	if(NetHandle!=-1)break;
	}
	// 確立が成功した場合のみ中の処理をする
	if( NetHandle != -1 )
	{ 
		// データ送信
		NetWorkSend( NetHandle , "接続者の名前" , 13 ) ;
	}
	while(  CheckHitKey( KEY_INPUT_ESCAPE ) == 0&&ClearDrawScreen()==0){
		// データがくるのを待つ
		while( !ProcessMessage() ){
		
			// 取得していない受信データ量を得る
			DataLength = GetNetWorkDataLength( NetHandle ) ;

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

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

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

		DataLength=0;

	}

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

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

	return 0 ;	// ソフトの終了
}
クライアント側はテストの為名前だけ送っています

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

Re: DxLibリファレンスの通信のプログラムを発展させたい

#13

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

softya(ソフト屋) さんが書きました:デバッグ開始(F5)で起動すれば問題のあるところで止まると思います。
何処の命令でしょうか?
こちらの件はどうなっていますか?
必要なので聞いていますので必ず回答をお願いします。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

わからんこ

Re: DxLibリファレンスの通信のプログラムを発展させたい

#14

投稿記事 by わからんこ » 13年前

わからんこ さんが書きました:すいません。クライアント側でした。

Client.exe の 0xda9000f7 でハンドルされていない例外が発生しました: 0xC0000005: Access violation
これでは回答になっていませんか?

これはサーバー側がメッセージを送ったら、このエラーがでてしまいます。

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

Re: DxLibリファレンスの通信のプログラムを発展させたい

#15

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

わからんこ さんが書きました:
わからんこ さんが書きました:すいません。クライアント側でした。

Client.exe の 0xda9000f7 でハンドルされていない例外が発生しました: 0xC0000005: Access violation
これでは回答になっていませんか?

これはサーバー側がメッセージを送ったら、このエラーがでてしまいます。
はい。これではClient.exe の何処かでメモリアクセスの範囲外例外が出たことしかわかりません。
何処での情報が抜けています。

わからんこさんが自分で直せる方法を理解しないと行けないのでお聞きしてます。
直すのは私ではなく、わからんこさんですよ。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

わからんこ

Re: DxLibリファレンスの通信のプログラムを発展させたい

#16

投稿記事 by わからんこ » 13年前

すいません。

色々弄っていると、

1>LINK : fatal error LNK1168: ファイル E:\Client\Debug\Client.exe を開いて書き込むことができません。

このエラーがでてしまって、先ほどのエラーが出せませんので、返事がすることが出来なくなってしまいました。。

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

Re: DxLibリファレンスの通信のプログラムを発展させたい

#17

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

わからんこ さんが書きました:すいません。

色々弄っていると、

1>LINK : fatal error LNK1168: ファイル E:\Client\Debug\Client.exe を開いて書き込むことができません。

このエラーがでてしまって、先ほどのエラーが出せませんので、返事がすることが出来なくなってしまいました。。
その場合はプログラムが終了していないのでタスクマネージャで、Client.exeをプロセス終了で強制終了してください。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

わからんこ

Re: DxLibリファレンスの通信のプログラムを発展させたい

#18

投稿記事 by わからんこ » 13年前

コード:

 #include "GV.h"

	int NetHandle ;				// 接続相手のネットワークハンドル
	int StringY ;				// 文字列表示領域の次に文字列を表示する時の行位置
	char ScreenString[ CHAT_LINENUM ][ MAX_STRLENGTH + 1 ] ;	// 画面に表示中のチャット文字列
	char name[251];
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
			 LPSTR lpCmdLine, int nCmdShow )
{
	//-----------------変数-----------------//
	char StrBuf[ 81 ],StrBuf2[ 81 ];
	IPDATA IP ;		// 接続用IPアドレスデータ
	int LostHandle;
	int DataLength=0 ;		// 受信データ量保存用変数
	//---------------------------------------//

	//-----------------初期設定------------------//
	SetDoubleStartValidFlag( TRUE ) ;
	ChangeWindowMode(TRUE);
	SetMainWindowText( "クライアント" ) ;
	if( DxLib_Init() == -1)return -1;	
	//-------------------------------------------//

	//--------------------関数-------------------//
	int ScreenStringAdd( char *AddString );
	int	ScreenStringDraw( void );
	//-------------------------------------------//


	// Ipの入力させる
	int i,j,k;
	// 接続先のIPの入力を促す	
	ScreenStringAdd( "アドレスを入力してください。" ) ;
	ScreenStringAdd( "入力は半角で各IP値は『.』で区切り、隙間は入れないで下さい" ) ;
	// 入力領域と文字出力領域との境界線を引く
	DrawLine( 0 , CHAT_LINENUM * FONT_SIZE , 640 , CHAT_LINENUM * FONT_SIZE , GetColor(255,255,255) ) ;

	while( !ProcessMessage() )
	{
		// IPの入力を行う
		KeyInputSingleCharString( 0 , INPUT_LINE * FONT_SIZE + 2 , 80 , StrBuf , FALSE ) ;
		
			// ピリオドが3つあるか調べる
			j = 0 ;
			for( i = 0 ; i < 80 ; i ++ )
			{
				if( StrBuf[ i ] == '.' ) j ++ ;
			}
				
		// もし3つピリオドがなかった場合は入力のし直し
			if( j != 3 )
			{
				ScreenStringAdd( "IP値の数が間違っています" ) ;
				continue ;
			}

		// 文字列からIPを抜き出す
			j = 0 ;
			k = 0 ;
			i = 0 ;
			while( !ProcessMessage() )
			{
			if( StrBuf[ i ] == '.' || StrBuf[ i ] == '\0' )
			{
				StrBuf2[ j ] = '\0' ;
				switch( k )
				{
				case 0 :IP.d1 = atoi( StrBuf2 ) ; break ;
				case 1 :IP.d2 = atoi( StrBuf2 ) ; break ;
				case 2 :IP.d3 = atoi( StrBuf2 ) ; break ;
				case 3 :IP.d4 = atoi( StrBuf2 ) ; break ;
				}
					k ++ ;
				if( k == 4 ) break ;
				
					j = 0 ;
			}else{
					StrBuf2[ j ] = StrBuf[ i ] ;
					j ++ ;
				}
					i ++ ;
			}
			

				// 接続中表示
				ScreenStringAdd( "接続中" ) ;

				// 接続を試みる
				NetHandle = ConnectNetWork(IP,10000) ;

				// 接続に成功したらループから抜ける
				if( NetHandle != -1 ) break ;

				// 接続失敗表示
				ScreenStringAdd( "接続は失敗しました" ) ;
	}

	// 接続成功表示
	ScreenStringAdd( "接続しました" );


	// 確立が成功した場合のみ中の処理をする
	if( NetHandle != -1 ){ 
	
		
		int Length;

	KeyInputString( 0, INPUT_LINE * FONT_SIZE + 2,20 , name, FALSE);
	Length = lstrlen(name) + 1 ;
	// データ送信
	NetWorkSend( NetHandle , name , Length ) ;
	}

	while( ProcessMessage()==0 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0 && ClearDrawScreen()==0){
		LostHandle=GetLostNetWork();
		if(LostHandle==NetHandle)break;

		
			// 取得していない受信データ量を得る
			DataLength = GetNetWorkDataLength( NetHandle ) ;

			// 取得してない受信データ量が0じゃない場合はループを抜ける
			if( DataLength != 0 ){
				// データ受信
				NetWorkRecv( NetHandle , StrBuf , DataLength ) ;	// データをバッファに取得

				// 受信したデータを描画
				DrawFormatString( 0, 0,GetColor( 255 , 255 , 255 ), "繋がってるかの状態 %s",StrBuf) ;
		
				
				DataLength=0;

			
			}

	}

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

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

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


アドバイスをもらい複数人の接続はうまくいくようになったのですが、

クライアント側がウィンドウの右端のバツを押して終了すると

バッファオーバーランが起こってしまうようになりました。

Run-Time Check Failure #2 - Stack around the variable 'StrBuf' was corrupted.

これは・・・StrBufに何か予期せぬ値が入っているから起こっているのでしょうか?

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

Re: DxLibリファレンスの通信のプログラムを発展させたい

#19

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

定義を見るとStrBufはナル文字も含めて81文字までです。※ 漢字だと40文字までです。
データ受信時にDataLength に対して81文字のオーバーチェックを行なって下さい。
もしオーバーするならサーバー側で超えないようにするか受信側で工夫して下さい。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

わからんこ

Re: DxLibリファレンスの通信のプログラムを発展させたい

#20

投稿記事 by わからんこ » 13年前

クライアント側に文字数を制限させました。

うまく行くことが出来ました。

次に本格的にデータをサーバーからクライアントに送るプログラムを作ってみます

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

Re: DxLibリファレンスの通信のプログラムを発展させたい

#21

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

ちなみに、こういう問題は良くセキュティ修正で聞くバッファーオーバーランの脆弱性と言います。
悪意のハッカーなら、このバッファーオーバーランを利用してPC内に潜入することが出来るわけです。
オンラインソフト作る場合は特に気をつけなくてはいけない問題です。

解決した場合は、解決チェックをお願いします。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

わからんこ

Re: DxLibリファレンスの通信のプログラムを発展させたい

#22

投稿記事 by わからんこ » 13年前

知り合い同士の通信でも、PCに外部から侵入を許してしまう事はありますか?

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

Re: DxLibリファレンスの通信のプログラムを発展させたい

#23

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

マイナーソフトだとPC侵入の可能性は低いでしょうがポートは常に無差別攻撃されていると思ったほうが良いでしょう。
そういう侵入経路を自動的に探すツールもあるみたいです。
なのでサーバー用に開放したポートに自分のプログラム以外の接続が起こることはあります。
それと怪しい接続の怪しいパケットが届く度に落ちていたら話にならないのである程度の堅牢性は必要と言えます。

もし偶然侵入されたらバックドアなどを仕掛けられて、何かの攻撃時の踏み台にされる可能性があります。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

わからんこ

Re: DxLibリファレンスの通信のプログラムを発展させたい

#24

投稿記事 by わからんこ » 13年前

今、作っているのは簡単なプログラムですが、人に渡すモノなので

その様なことが起こるかも知れないプログラムを控えたほうがいいですね。

ある程度、プログラムを強固なものにすることは、私でも出来ますでしょうか?

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

Re: DxLibリファレンスの通信のプログラムを発展させたい

#25

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

わからんこ さんが書きました:今、作っているのは簡単なプログラムですが、人に渡すモノなので

その様なことが起こるかも知れないプログラムを控えたほうがいいですね。

ある程度、プログラムを強固なものにすることは、私でも出来ますでしょうか?
やることは
1)バッファサイズをオーバーさせない
2)受信したデータの中身を検証して変なデータなら捨てる。
3)検証用の情報をデータに埋め込む
とちゃんとやれば大丈夫です。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

わからんこ

Re: DxLibリファレンスの通信のプログラムを発展させたい

#26

投稿記事 by わからんこ » 13年前

コード:

#include "GV.h"

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
			LPSTR lpCmdLine, int nCmdShow )
{

	//-------------最初の設定--------------//
	SetDrawScreen( DX_SCREEN_BACK );
	ChangeWindowMode(TRUE);
	SetMainWindowText( "サーバー" ) ;

	if( DxLib_Init() == -1 )return -1;// エラーが起きたら直ちに終了
	
	//-------------------------------------//


	//-------------変数----------------//
	char StrBuf[MAX_CONNECT_NUM][ 256 ];// データバッファ
	int NetHandle[MAX_CONNECT_NUM],LostHandle[MAX_CONNECT_NUM];	// ネットワークハンドル
	int DataLength[MAX_CONNECT_NUM]; ;// 受信データ量保存用変数
	IPDATA Ip[MAX_CONNECT_NUM];// 接続先IPアドレスデータ
	int Num,Flag,PortNum;
	int count[MAX_CONNECT_NUM];
	char Name[MAX_CONNECT_NUM][21];
	//----------------------------------//

	//---------------関数---------------//
	int Net_Init(void);


	//----------------------------------//


	// 接続してくるのを待つ状態にする
	PreparationListenNetWork( PortNum=Net_Init() ) ;
	
	
	//初期化
	for(int i=0;i<MAX_CONNECT_NUM;i++){
		strcpy(  StrBuf[i], "未受信" ) ;
		strcpy(  Name[i], "名前未受信" ) ;
		NetHandle[i] = -1 ;
		count[i]=0;
	}
	//ESCキーが押されるまでループ
	while( ScreenFlip()==0&&ProcessMessage()==0 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0&&	ClearDrawScreen()==0)
	{ 
		//開放中のポート番号表示
		DrawFormatString( 0, FONT_SIZE*2 ,GetColor(255,255,255),"現在開放中ポート番号 %d 番",PortNum);

		//接続が切れてるかチェック
		for(int i=0;i<MAX_CONNECT_NUM;i++){
			LostHandle[i]=GetLostNetWork();
		if(LostHandle[i]==NetHandle[i]){
			strcpy(  Name[i], "名前未受信" ) ;
			strcpy(  StrBuf[i], "未受信" ) ;
			NetHandle[i]=-1;
			count[i]=0;
		
		}
		}

		//配列番号を決める
		for(int i=0;i<MAX_CONNECT_NUM;i++){
			if(NetHandle[i]==-1){
				Num=i;
				Flag=0;
				break;
			}else{
				Flag=1;
			}
		}

		//接続人数限界以上じゃなかったらつなげる
		if(Flag != 1)
			NetHandle[Num] = GetNewAcceptNetWork();

		//ip保存
		GetNetWorkIP(NetHandle[Num] , &Ip[Num]) ;


		//接続者の名前を表示
		for(int i=0;i<MAX_CONNECT_NUM;i++){
			//データを受信してる
			if( GetNetWorkDataLength( NetHandle[i] ) != -1 &&GetNetWorkDataLength( NetHandle[i])> sizeof( int )){
				if(count[i]==0){
				DataLength[i] = GetNetWorkDataLength( NetHandle[i] ) ;	// データの量を取得
				NetWorkRecv( NetHandle[i] , Name[i] , DataLength[i] );// データをバッファに取得
				
				count[i]=1;
				}else{	
				// データ受信
				DataLength[i] = GetNetWorkDataLength( NetHandle[i] ) ;	// データの量を取得
				NetWorkRecv( NetHandle[i] , StrBuf[i] , DataLength[i] );// データをバッファに取得
				DrawFormatString( 0, FONT_SIZE*10 ,GetColor(255,255,255),"Check");
				}
			}
			if(NetHandle[i]!=-1){
			// 受信したデータを描画
			DrawFormatString( 0, 50+(FONT_SIZE*i),GetColor( 255 , 255 , 255 ), "No %d :接続中 IP:%d.%d.%d.%d  名前:%s "
															,i,Ip[i].d1,Ip[i].d2,Ip[i].d3,Ip[i].d4 ,Name[i] ) ;
			DrawFormatString( 0, 50+(FONT_SIZE*(i+1)),GetColor( 255 , 255 , 255 ), "受信内容:%s",StrBuf[i]);

			}
		}

		
		//// 受信成功のデータを送信
		//for(int i=0;i<MAX_CONNECT_NUM;i++){
		//	for(int j=0;j<MAX_CONNECT_NUM;j++){
		//		if(NetHandle[j]!=-1 && GetNetWorkDataLength( NetHandle[j])> sizeof( int )){
		//			DrawFormatString( 0, FONT_SIZE*10 ,GetColor(255,255,255),"hello world");
		//			NetWorkSend( NetHandle[j] , StrBuf[i] , DataLength[i]+1);
		//			}
		//	}
		//}

	}

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

	return 0 ;	// ソフトの終了
} 
相手が名前を入力してもらって名前を表示させることはできたのですが

クライアントが二回目以降データ送信してきたものはメッセージとして受け取って名前と同じ用に表示させたいのですが

表示することは出来ません。

名前のデータ受け取りが出来たので同じ要領かと思い書いたプログラムなのですが何がいけないのでしょうか?

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

Re: DxLibリファレンスの通信のプログラムを発展させたい

#27

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

デバッガで動作を確認されましたか?
わからんこ さんが書きました: 相手が名前を入力してもらって名前を表示させることはできたのですが
クライアントが二回目以降データ送信してきたものはメッセージとして受け取って名前と同じ用に表示させたいのですが
表示することは出来ません。
名前のデータ受け取りが出来たので同じ要領かと思い書いたプログラムなのですが何がいけないのでしょうか?
この説明だけだと何が起こっているか、こちらには分かりません。

>表示することは出来ません。
じゃあ何が起こったのでしょうか?

あとインデントを正確に行うようにお願いします。バグの元にもなります。
「mixcpp/投稿前チェックリスト - PukiWiki」
http://uchan.net/w/index.php?mixcpp%2F% ... 5%B9%A5%C8
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

わからんこ

Re: DxLibリファレンスの通信のプログラムを発展させたい

#28

投稿記事 by わからんこ » 13年前

受信内容:        
       ↑何も表示されません。

本来はここに相手のメッセージを表示させたいのですが・・・

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

Re: DxLibリファレンスの通信のプログラムを発展させたい

#29

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

わからんこ さんが書きました:受信内容:        
       ↑何も表示されません。

本来はここに相手のメッセージを表示させたいのですが・・・
デバッガでの動作確認はされていないのでしょうか?
必要だから聞いていますので必ずお答え下さい。

あとクライアントで送信していることは確認されていますか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

わからんこ

Re: DxLibリファレンスの通信のプログラムを発展させたい

#30

投稿記事 by わからんこ » 13年前

本格的にプログラムを書いたことがないので

デバッガでの動作確認と言われても、どうすればよいかわかりません。

デバッガでの動作確認とはなんでもいいのでデバッガをダウンロードしてきて使うのか
それとも、こういったプログラムに適したデバッガがあるのでしょうか?

すいません。まだプログラムに触れて日が浅いので、初歩的な事で詰まってしまいまして・・・


クライアント側は確かに送信しています。

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

Re: DxLibリファレンスの通信のプログラムを発展させたい

#31

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

わからんこ さんが書きました:本格的にプログラムを書いたことがないので

デバッガでの動作確認と言われても、どうすればよいかわかりません。

デバッガでの動作確認とはなんでもいいのでデバッガをダウンロードしてきて使うのか
それとも、こういったプログラムに適したデバッガがあるのでしょうか?

すいません。まだプログラムに触れて日が浅いので、初歩的な事で詰まってしまいまして・・・


クライアント側は確かに送信しています。
分からないでも良いので、やったか?やれなかったのか?の情報が欲しいわけです。
スルーされるのが一番問題で原因の追求を難しくします。

VisualC++であればデバッガ付属していますが開発環境に何をお使いですか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

わからんこ

Re: DxLibリファレンスの通信のプログラムを発展させたい

#32

投稿記事 by わからんこ » 13年前

VisualC++2010 でやっています。

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

Re: DxLibリファレンスの通信のプログラムを発展させたい

#33

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

VisualC++2010であれば次のように使います。

「プログラムのデバッグ実行」
http://cvwww.ee.ous.ac.jp/vc10prog.html#7

プログラムを通っているポイントと変数の変化をチェックできるので、受信している部分とか受信ハンドルを確認して下さい。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

わからんこ

Re: DxLibリファレンスの通信のプログラムを発展させたい

#34

投稿記事 by わからんこ » 13年前

見よう見まねですが、

送信部分にブレークポイントをおき、変数の変化を見てみたのですが

クライアント側は確かに送信できていると思いますが、

受信側のStrBuf(相手の送信内容を受け取る配列)の中身には

相手が送ったものでなく、よくわからない記号た、アルファベットが入っています。

今、プログラムにその様な文字列が表示されることはありません

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

Re: DxLibリファレンスの通信のプログラムを発展させたい

#35

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

通信系は初心者が・・・とか言っている場合ではなくて中級者のプログラミング技術を身に着けていかないと作ることができません。
WireSharkもデバッガもちゃんと使いこなさないとバグが取れないので頑張ってください。
わからんこ さんが書きました:送信部分にブレークポイントをおき、変数の変化を見てみたのですが

クライアント側は確かに送信できていると思いますが、
名前以外の送信処理は行われていると言うことですね?
わからんこ さんが書きました:受信側のStrBuf(相手の送信内容を受け取る配列)の中身には
相手が送ったものでなく、よくわからない記号た、アルファベットが入っています。
今、プログラムにその様な文字列が表示されることはありません
ハンドルは確認してもらいましたか?
それとStrBufの状態は何処で確認しましたか?
NetWorkRecv( NetHandle , StrBuf , DataLength );// データをバッファに取得
この行の次の行にF10で進めないとNetWorkRecvは行われていませんのでStrBufにも値が入りません。
DataLengthにもちゃんと送信したサイズは入っていますか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

わからんこ

Re: DxLibリファレンスの通信のプログラムを発展させたい

#36

投稿記事 by わからんこ » 13年前

ブレークポイントをつくり、配列に入る数字や文字、パケットなど色々調べました。

結果、受け取りの仕組みを変えたところ、うまくいくようになりました。


折角うまくいったのに、クライアント側のコードをコンパイルした時に、プログラムが実行されなくなりました。


「プログラム '[4496] Client.exe: ネイティブ' はコード 255 (0xff) で終了しました。」と表示だけされます。

これはコンパイルは通っているけど、VisualC++2010で実行されなくなっただけなのか、

プログラムに不具合があって実行されていないのかどちらなのでしょうか?

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

Re: DxLibリファレンスの通信のプログラムを発展させたい

#37

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

わからんこ さんが書きました:ブレークポイントをつくり、配列に入る数字や文字、パケットなど色々調べました。

結果、受け取りの仕組みを変えたところ、うまくいくようになりました。


折角うまくいったのに、クライアント側のコードをコンパイルした時に、プログラムが実行されなくなりました。


「プログラム '[4496] Client.exe: ネイティブ' はコード 255 (0xff) で終了しました。」と表示だけされます。

これはコンパイルは通っているけど、VisualC++2010で実行されなくなっただけなのか、

プログラムに不具合があって実行されていないのかどちらなのでしょうか?
プログラムが不具合があって実行されないって事でしょう。
デバッガの出番です。デバッグ開始で異常なポイントで処理が止まりませんか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

わからんこ

Re: DxLibリファレンスの通信のプログラムを発展させたい

#38

投稿記事 by わからんこ » 13年前

すこしずつしか前進していませんが、すこし形になってきました。

今のところ、

サーバー側
相手のIP表示と名前、相手が一番最近入力したメッセージを表示
名前とメッセージを接続している全員に送信

クライアント側
文字入力と受信
他の接続者のメッセージを受信

とすこしリファレンスのプログラムより前進した気がします

しかし、まだダメな事もありますので、まだもうちょっとがんばります

わからんこ

Re: DxLibリファレンスの通信のプログラムを発展させたい

#39

投稿記事 by わからんこ » 13年前

テストが終わったので、再び発展を目指そうとしています、

今までは文字列だけ送信していましたが、もっと複数のデータをやり取りできるように

しようと思いました。

そこで、構造体をつくり、送信し、構造体を受信させようと考えましたが

構造体で一度にたくさんのデータを送るのと、データを複数回に分けて送るのではどちらのほうが

効率が良いのでしょうか?

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

Re: DxLibリファレンスの通信のプログラムを発展させたい

#40

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

要求されるレスポンスタイム(応答時間)やゲーム内容や自分の技量で決めるべきです。
大量のデータを送信するならマトめてのほうが無駄がないでしょうが、それなりに時間がかかります。
分割で送って問題ないように組んだほうがレスポンスタイムは良くなりますがプログラムが複雑になるかも知れません。

つまり、最適の着地点というのは最初に書いた条件のミックスで決まるものですから常に正解の万能解はありません。
実験して経験則で決めたほうが良いとも言えます。
あとなるべく接続するであろう中でも速度の遅い回線の事を意識しないとオンラインゲームは成り立たなくなります。

【補足】
大事なことを忘れていました。
うまく動いたコードを貼り付けていただくようにお願いします。ここのルールとなっております。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

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

Re: DxLibリファレンスの通信のプログラムを発展させたい

#41

投稿記事 by h2so5 » 13年前

アプリケーション側でデータを小分けにしても、
TCPレイヤーで自動的にまとめて送信されてしまい意味がない場合もあると思います。

わからんこ

Re: DxLibリファレンスの通信のプログラムを発展させたい

#42

投稿記事 by わからんこ » 13年前

勉強の為に、http://dixq.net/forum/viewtopic.php?f=3&t=10029 このトピックを元に自分なりに

発展を目指しました。

発展元
http://homepage2.nifty.com/natupaji/DxL ... m.html#N21

一応うまく動きましたが、まだなにかダメなとこがあるかも知れませんがご容赦を

発展元のプログラムを受信側と送信側に分割して作りました。

送信側はあまり変えていませんが、受信側は複数が接続できるような動きを目指して変えました。

コード:

#include "GV.h"

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
			LPSTR lpCmdLine, int nCmdShow )
{

	//-------------最初の設定--------------//
	SetDrawScreen( DX_SCREEN_BACK );
	ChangeWindowMode(TRUE);
	SetMainWindowText( "サーバー" ) ;
	SetAlwaysRunFlag(TRUE);
	if( DxLib_Init() == -1 )return -1;// エラーが起きたら直ちに終了
	
	//-------------------------------------//


	//-------------変数----------------//
	
	int NetHandle[MAX_CONNECT_NUM],LostHandle[MAX_CONNECT_NUM];	// ネットワークハンドル
	int DataLength[MAX_CONNECT_NUM] ;// 受信データ量保存用変数
	int NameLength[MAX_CONNECT_NUM] ;// 受信データ量保存用変数
	int SendLength[MAX_CONNECT_NUM] ;// 受信データ量保存用変数
	IPDATA Ip[MAX_CONNECT_NUM];// 接続先IPアドレスデータ
	int Num,Flag,PortNum;
	int count[MAX_CONNECT_NUM];
	char Name[MAX_CONNECT_NUM][21];
	char StrBuf[MAX_CONNECT_NUM][ 41 ];// データバッファ
	//送信用
	char StrBuf2[MAX_CONNECT_NUM][ 61 ];// データバッファ
	int Check[MAX_CONNECT_NUM];
	//----------------------------------//

	//---------------関数---------------//
	int Net_Init(void);
	
	//----------------------------------//


	// 接続してくるのを待つ状態にする
	PreparationListenNetWork( PortNum=Net_Init() ) ;
	
	
	//初期化
	for(int i=0;i<MAX_CONNECT_NUM;i++){
		//strcpy(  StrBuf[i], "未受信" ) ;
		strcpy(  Name[i], "名前未受信" ) ;
		NetHandle[i] = -1 ;
		count[i]=0;
		Check[i]=1;
	}
	//ESCキーが押されるまでループ
	while( ScreenFlip()==0&&ProcessMessage()==0 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0&&ClearDrawScreen()==0)
	{ 
		//開放中のポート番号表示
		DrawFormatString( 0, FONT_SIZE*2 ,GetColor(255,255,255),"現在開放中ポート番号 %d 番",PortNum);

		//接続が切れてるかチェック
		for(int i=0;i<MAX_CONNECT_NUM;i++){
			LostHandle[i]=GetLostNetWork();
		if(LostHandle[i]==NetHandle[i]){
			strcpy(  Name[i], "名前未受信" ) ;
			strcpy(  StrBuf[i], "" ) ;
			NetHandle[i]=-1;
			count[i]=0;
		
			}
		}

		//配列番号を決める
		for(int i=0;i<MAX_CONNECT_NUM;i++){
			if(NetHandle[i]==-1){
				Num=i;
				Flag=0;
				break;
			}else{
				Flag=1;
			}
		}

		//接続人数限界以上じゃなかったらつなげる
		if(Flag != 1)
			NetHandle[Num] = GetNewAcceptNetWork();

		//ip保存
		GetNetWorkIP(NetHandle[Num] , &Ip[Num]) ;


		//接続者の名前を表示
		for(int i=0;i<MAX_CONNECT_NUM;i++){
			//データを受信してる
			if( GetNetWorkDataLength( NetHandle[i] ) != -1 &&GetNetWorkDataLength( NetHandle[i])> sizeof( int )){
				if(count[i]==0){
				NameLength[i] = GetNetWorkDataLength( NetHandle[i] ) ;	// データの量を取得
				NetWorkRecv( NetHandle[i] , Name[i] , NameLength[i] );// データをバッファに取得
				
				count[i]=1;
				}else{	
					
				// データ受信
				 DataLength[i] = GetNetWorkDataLength( NetHandle[i] ) ;	// データの量を取得
				NetWorkRecv( NetHandle[i] , StrBuf[i] , DataLength[i] );// データをバッファに取得

				int k;
				for(k=0;k<MAX_CONNECT_NUM;k++){
				if(i!=k)
					Check[k]=0;
				else
					Check[k]=1;
				}

				}
			}
			if(NetHandle[i]!=-1){
			// 受信したデータを描画
				int tmp=0;
				if(i==1)tmp=1;
				else tmp=0;

				DrawFormatString( 0, 50+(FONT_SIZE*  ((i*i)+tmp) ),GetColor( 255 , 255 , 255 ), "No %d :接続中 IP:%d.%d.%d.%d  名前:%s サイズ:%d "
																		,i,Ip[i].d1,Ip[i].d2,Ip[i].d3,Ip[i].d4 ,Name[i],NameLength[i]) ;
				DrawFormatString( 0, 50+(FONT_SIZE*  ((i*i)+1+tmp)  ),GetColor( 255 , 255 , 255 ), "受信内容:%s サイズ %d",StrBuf[i],DataLength[i]);
		
			//---送信配列準備場所---//
			strcpy(StrBuf2[i],Name[i]);
			strcat(StrBuf2[i], " : ");
			strcat(StrBuf2[i],StrBuf[i]);

			SendLength[i] = lstrlen(StrBuf2[i]) + 6 ;
			//----------------------//

			}

			// 受信成功のデータを送信
			for(int j=0;j<MAX_CONNECT_NUM;j++){
				if(i!=j && NetHandle[j]!=-1 && DataLength[i]>0 && Check[j]!=1){
					NetWorkSend( NetHandle[j],StrBuf2[i],SendLength[i]);
					Check[j]=1;
			}	}
		
		}
	}

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

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

//ポート入力を行う
int Net_Init(void){
		
	int Color=GetColor(255,255,255);
	int PortNum=0;
	// 入力領域と文字出力領域との境界線を引く
	DrawLine( 0 , CHAT_LINENUM * FONT_SIZE , 640 , CHAT_LINENUM * FONT_SIZE , Color ) ;

	DrawString( 0, 0 ,"接続受付中", Color ) ;
	DrawString( 0, FONT_SIZE ,"現在開放しているポート番号を入力して下さい。", Color ) ;
	
	PortNum=KeyInputNumber( 0, (CHAT_LINENUM * FONT_SIZE)+FONT_SIZE,  65535 , 0 ,FALSE) ;
	
	return PortNum;	
	}
 

わからんこ

Re: DxLibリファレンスの通信のプログラムを発展させたい

#43

投稿記事 by わからんこ » 13年前

h2so5 さんが書きました:アプリケーション側でデータを小分けにしても、
TCPレイヤーで自動的にまとめて送信されてしまい意味がない場合もあると思います。
そうなんですか、ではまとめて送るプログラムをとりあえず考えて見ます。

わからんこ

Re: DxLibリファレンスの通信のプログラムを発展させたい

#44

投稿記事 by わからんこ » 13年前

色々考えて、ゴチャゴチャになったので、紙の上で構造を書き出しているのですが、

構造体を送ると際は、サーバー側のプログラムにも、

その構造体を定義しておく必要がありますか?

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

Re: DxLibリファレンスの通信のプログラムを発展させたい

#45

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

わからんこ さんが書きました:色々考えて、ゴチャゴチャになったので、紙の上で構造を書き出しているのですが、

構造体を送ると際は、サーバー側のプログラムにも、

その構造体を定義しておく必要がありますか?
中身を触らずに何処かへ投げるだけならサイズだけわかっていれば良いです。
※ クライアント→サーバー→クライアントと言うようにサーバーを経由するだけの場合。
サーバーが中身を参照・変更するなら構造体の定義は必要です。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

わからんこ

Re: DxLibリファレンスの通信のプログラムを発展させたい

#46

投稿記事 by わからんこ » 13年前

サーバー経由させる際、受信して

送信するまではどこに一時保管しておけばいいのですか?

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

Re: DxLibリファレンスの通信のプログラムを発展させたい

#47

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

わからんこ さんが書きました:サーバー経由させる際、受信して

送信するまではどこに一時保管しておけばいいのですか?
リングバッファを用意するか、その都度malloc(C++ならnew)して管理するのが一般的です。
まぁ、宛先も管理する必要があるのでリングバッファ・キューの類は必須でしょう。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

わからんこ

Re: DxLibリファレンスの通信のプログラムを発展させたい

#48

投稿記事 by わからんこ » 13年前

リングバッファ・キューを行うには、

待ち行列を勉強してきたらいいですか?

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

Re: DxLibリファレンスの通信のプログラムを発展させたい

#49

投稿記事 by beatle » 13年前

C++の標準ライブラリを使っていいなら deque がリングバッファ(キューの実装のやり方の一つ)になっております。
C++編(標準ライブラリ) 第4章 deque

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

Re: DxLibリファレンスの通信のプログラムを発展させたい

#50

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

わからんこ さんが書きました:リングバッファ・キューを行うには、

待ち行列を勉強してきたらいいですか?
C言語 リングバッファ
C言語 キュー
C言語 FIFO
で検索すれば色々出てきますよ。
基本的なアルゴリズムですから覚えておいて損はないですし今回は必要だと思います。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

わからんこ

Re: DxLibリファレンスの通信のプログラムを発展させたい

#51

投稿記事 by わからんこ » 13年前

FIFOとかは最近勉強したのでわかりますが、

残りはわからないので勉強してきます

わからんこ

Re: DxLibリファレンスの通信のプログラムを発展させたい

#52

投稿記事 by わからんこ » 13年前

intの変数が5個
floatの変数が5個
charで要素数21の配列ひとつ

この構造体は配列で4つあるとして

いっぺんに送るのは多いですか?

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

Re: DxLibリファレンスの通信のプログラムを発展させたい

#53

投稿記事 by h2so5 » 13年前

それは質問になっていないような気がします。
例えば、「3,000円は高いですか?」とだけ聞かれても答えようがないのと同じです。

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

Re: DxLibリファレンスの通信のプログラムを発展させたい

#54

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

わからんこ さんが書きました:intの変数が5個
floatの変数が5個
charで要素数21の配列ひとつ

この構造体は配列で4つあるとして

いっぺんに送るのは多いですか?
1)合計するとそれは何バイトになりますか?(当然把握しているべきです)
2)そして、そのサイズを大きいと思いますか?
3)あとバイナリデータファイルを扱うことに慣れていますか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

わからんこ

Re: DxLibリファレンスの通信のプログラムを発展させたい

#55

投稿記事 by わからんこ » 13年前

368バイトあるのですが

個人的には小さいかなと、

質問が漠然としすぎてすいません。

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

Re: DxLibリファレンスの通信のプログラムを発展させたい

#56

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

わからんこ さんが書きました:368バイトあるのですが

個人的には小さいかなと、

質問が漠然としすぎてすいません。
私も小さいと思います。

それと
intの変数が5個
floatの変数が5個
charで要素数21の配列ひとつ
が4つだと368は計算が合いません。

そういう意味で
3)あとバイナリデータファイルを扱うことに慣れていますか?
が不安です。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

わからんこ

Re: DxLibリファレンスの通信のプログラムを発展させたい

#57

投稿記事 by わからんこ » 13年前

すいません。

VECTOR型2つ書き忘れていました。

バイナリデータファイルの扱いはしたことがありません。

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

Re: DxLibリファレンスの通信のプログラムを発展させたい

#58

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

それでも計算が合わないので、こういう知識がないと危ういということです。

「データ型のアラインメントとは何か,なぜ必要なのか?」
http://www5d.biglobe.ne.jp/~noocyte/Pro ... nment.html
こういうことがバイナリの知識ってことですね。

データサイズについてはダミーを付けてでも増やしてください。
そうしないと思ったタイミングで送信されない可能性があります。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

閉鎖

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