ページ 1 / 1
他マシン接続
Posted: 2012年7月18日(水) 19:40
by わからんこ
http://dixq.net/forum/viewtopic.php?f=3&t=5386
ここを見つけて、他のパソコンとの通信を自分でもやってみたいと
思ったのですが、通信サンプルプログラムすら、うまく行きません。
ポート開放し、グローバルIPアドレスを相手に教え入力してもらうと、相手は接続に成功するのですが、
ホスト側の私は接続を待ちます。のままです。
私は勉強の為サンプルなどは手打ちしています。そのせいで、括弧の位置が違うなどで予期せぬ動作をすることなどが
ありますが、今回は自分の持っているノートパソコンとプライベートIPアドレスを渡し通信してみたところ、
うまくいったので、コードにミスはないと思います。
うまくいかない原因はなんでしょうか?
Re: 他マシン接続
Posted: 2012年7月18日(水) 19:55
by h2so5
「通信サンプルプログラム」とは何のプログラムでしょうか?
相手が接続に成功したとはどういう状況なのかも詳しく書いてください。
Re: 他マシン接続
Posted: 2012年7月18日(水) 19:58
by わからんこ
コード:
#include "DxLib.h"
#include <string.h>
#define CHAT_LINENUM 20 // チャット中の文字列を表示する行数
#define MAX_STRLENGTH 80 // チャットで1行で入力できる文字数
#define INPUT_LINE 21 // チャットで入力領域となる画面上の行位置
#define FONT_SIZE 16 // フォントのサイズ
int InputHandle ; // 入力ハンドル
int StringY ; // 文字列表示領域の次に文字列を表示する時の行位置
int NetHandle ; // 接続相手のネットワークハンドル
char ScreenString[ CHAT_LINENUM ][ MAX_STRLENGTH + 1 ] ; // 画面に表示中のチャット文字列
int ScreenStringAdd( char *AddString ) ; // チャット文字列を追加する
int ScreenStringDraw( void ) ; // チャットの現在の状態を画面に表示する
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow )
{
char Key ;
// DXライブラリ初期化
if( DxLib_Init() == -1 )
{
return -1 ;
}
// 入力領域と文字出力領域との境界線を引く
DrawLine( 0 , CHAT_LINENUM * FONT_SIZE , 640 , CHAT_LINENUM * FONT_SIZE , GetColor( 255 , 255 , 255 ) ) ;
// 接続を待つか接続をするか入力してもらう
ScreenStringAdd( "接続を待つ場合はZキーを、接続をする場合はXキーを押してください" ) ;
// どちらのキーが押されるか監視する
{
while( !ProcessMessage() )
{
if( CheckHitKey( KEY_INPUT_Z ) )
{
Key = 'Z' ;
break ;
}
if( CheckHitKey( KEY_INPUT_X ) )
{
Key = 'X' ;
break ;
}
}
}
// 押されたキーによって処理を分岐する
switch( Key )
{
// 接続を待つ場合
case 'Z':
// 接続待ち状態にする
PreparationListenNetWork( 9850 ) ;
// 接続があるまで待つ表示
ScreenStringAdd( "接続があるまで待ちます" ) ;
// 接続があるまでここでループ
while( !ProcessMessage() )
{
// 新しい接続があった場合はそのネットハンドルを保存する
NetHandle = GetNewAcceptNetWork() ;
// 新しい接続があった場合はループを出る
if( NetHandle != -1 ) break ;
}
// 接続待ちを解除
StopListenNetWork() ;
break ;
// こちらから接続をする場合
case 'X' :
{
char StrBuf[ 81 ] , StrBuf2[ 81 ] ;
IPDATA IP ;
int i , j , k ;
// 入力を行う
while( !ProcessMessage() )
{
// 接続先のIPの入力を促す
ScreenStringAdd( "接続先のIPを入力してください" ) ;
ScreenStringAdd( "入力は半角で各IP値は『.』で区切り、隙間は入れないで下さい" ) ;
// 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, 9850 ) ;
// 接続に成功したらループから抜ける
if( NetHandle != -1 ) break ;
// 接続失敗表示
ScreenStringAdd( "接続は失敗しました" ) ;
}
}
break ;
}
// 接続成功表示
ScreenStringAdd( "接続しました" ) ;
// 文字列入力ハンドルを作成する
InputHandle = MakeKeyInput( 80 , FALSE , FALSE , FALSE ) ;
// 作成した入力ハンドルをアクティブにする
SetActiveKeyInput( InputHandle ) ;
// チャットループ
while( !ProcessMessage() )
{
// 切断確認
if( GetLostNetWork() == NetHandle ) break ;
// 受信した文字列がある場合は受信する
if( GetNetWorkDataLength( NetHandle ) > sizeof( int ) )
{
int StrLength ;
char Message[81] ;
// 受信した文字列の長さを得る
NetWorkRecvToPeek( NetHandle , &StrLength , 4 ) ;
// 受信するはずの文字列長より受信されている文字数が少ない場合は
// 何もせずもどる
if( StrLength + 4 <= GetNetWorkDataLength( NetHandle ) )
{
// 文字列の長さを得る
NetWorkRecv( NetHandle , &StrLength , 4 ) ;
// メッセージを受信
NetWorkRecv( NetHandle , Message , StrLength ) ;
// 画面に表示
ScreenStringAdd( Message ) ;
}
}
// 文字列入力
{
// 文字列の入力が終っている場合は送信する
if( CheckKeyInput( InputHandle ) == 1 )
{
char Message[ 81 ] ;
int StrLength ;
// 入力された文字列を取得する
GetKeyInputString( Message , InputHandle ) ;
// 入力された文字列の長さを送信する
// +1 は終端文字('\0')を含めるため
StrLength = lstrlen( Message ) + 1 ;
NetWorkSend( NetHandle , &StrLength , sizeof( int ) ) ;
// 文字列を送信
NetWorkSend( NetHandle , Message , StrLength ) ;
// 自分のとこにも表示する
ScreenStringAdd( Message ) ;
// 入力文字列を初期化する
SetKeyInputString( "" , InputHandle ) ;
// 再度インプットハンドルをアクティブにする
SetActiveKeyInput( InputHandle ) ;
}
// 画面に入力中の文字列を描画する
DrawBox( 0 , INPUT_LINE * FONT_SIZE + 2 , 640 , 480 , 0 , TRUE ) ;
DrawKeyInputString( 0 , INPUT_LINE * FONT_SIZE + 2 , InputHandle ) ;
DrawKeyInputModeString( 640 , 480 ) ;
}
// 時間待ち
WaitTimer( 32 ) ;
}
// 切断確認処理
ScreenStringAdd( "切断しました" ) ;
// 時間待ち
WaitTimer( 3000 ) ;
DxLib_End() ; // DXライブラリ使用の終了処理
return 0 ; // ソフトの終了
}
これなんですが、相手だけ接続に成功しましたとでます
Re: 他マシン接続
Posted: 2012年7月18日(水) 22:08
by softya(ソフト屋)
怪しい動作になると思うのであちこちのWaitTimer()とか沢山のrocessMessage()とかは避けたほうが良いと思います。
まずサンプルにあるコードそのままなどシンプルな環境でテストして下さい。
それとWireSharkなどパケットキャプチャを使いこなすことは通信系のデバッグのため必須の事項です。
パケットが外部に向かってちゃんと出て行っているのか?
外部からのパケットはちゃんと来ているのかを確認して下さい。
ご自身のルータなどやファイアウォールソフトなども疑う必要があります。
Re: 他マシン接続
Posted: 2012年7月18日(水) 23:40
by わからんこ
ご指摘の通り、パケットの状態を見てきましたが、外部からのパケットはきていませんでした。
接続側の接続状態から抜けれない理由がわかりましたが、
接続する側は、確かに私が開放したポートに接続することが出来ています。
送信側に接続できているのに、受信側は接続できないです。
受信側のプログラムにグローバルIPアドレス以外に何か与えないと、個別のパソコンまで
パケットが届かないのでしょうか?
Re: 他マシン接続
Posted: 2012年7月18日(水) 23:49
by h2so5
PreparationListenNetWork関数が成功しているのかが怪しいですね。
戻り値を確認してみてください。
Re: 他マシン接続
Posted: 2012年7月19日(木) 00:09
by わからんこ
戻り値は-1ですね・・・
Re: 他マシン接続
Posted: 2012年7月19日(木) 00:41
by h2so5
もしかして他のプロセスが9850番ポートを使用しているのかもしれません。
Re: 他マシン接続
Posted: 2012年7月19日(木) 03:06
by わからんこ
Re: 他マシン接続
Posted: 2012年7月19日(木) 03:11
by h2so5
プログラムに間違いがなくても環境によって動かないことはあります。
相手側が接続できているのにこちら側で接続出来ていないということは、
こちら側で別のプロセスがポートを使用していて、それと相手側が接続している可能性があります。
Re: 他マシン接続
Posted: 2012年7月19日(木) 03:24
by わからんこ
ANHTTPでポートを開いているのですが、それがダメなんですかね?
これに相手から接続があると、相手のIPがでて接続中と、このソフトにはでるのですが
プログラムでは接続中にならないので・・・・
Re: 他マシン接続
Posted: 2012年7月19日(木) 05:28
by へにっくす
わからんこ さんが書きました:ANHTTPでポートを開いているのですが、それがダメなんですかね?
これに相手から接続があると、相手のIPがでて接続中と、このソフトにはでるのですが
プログラムでは接続中にならないので・・・・
・・・
ふつうサーバ自身がポートを開き待機するのです。
なぜ別プロセスで開いているポートを、他のプロセスが使用できると思ってるんですか?
#AnHTTPを実行しないでやってみてください。
Re: 他マシン接続
Posted: 2012年7月19日(木) 16:06
by わからんこ
友達と思考錯誤した上で、繋げる事が出来ました。
へにっくす さんの言うように別のプロセスが邪魔してたみたいでした。
まだ知識不足で、ありえない質問をしているかも知れませんが
これからもよろしくお願いします。