コンピュータを楽しもう!!

今、自分が面白くていろいろやってみたことを書き綴りたいと思います。連絡先はtarosa.yでgmail.comです。

DSでPeer to Peer通信?

今回はポケットWiFi経由でDSをつなぐ話です。やっと「埒」が明きました。皇帝さんにデーモン側のソケット通信について教えてもらいました。いやぁ、目から鱗とはこのことで、dswifiのライブラリ群はunix等のライブラリと同じなんですね。そこのところを全然分かっていませんでした。ネットでクグッて見ると、プログラムの例が山のように出てきました。皇帝さんいろいろと教えていただいてありがとうございます。

tcp通信でポートにつなぎに行く

クライアント側ということになりますが、サーバ名とポートを指定して相手のDSに接続しに行くプログラムを書きました。

defineはこんな感じで・・・。

//WiFi Error
#define WIFI_SOCKET_ERROR		-1
#define WIFI_CONNECT_ERROR		-2
#define WIFI_BIND_ERROR			-3
#define WIFI_LISTEN_ERROR		-4
#define WIFI_TIMEOUT_ERROR		-5
#define WIFI_ACCEPT_ERROR		-6

接続するプログラム

//**************************************************
// 指定されたIPアドレスの機器の指定ポートにつなぎにいきます
// ipAdd:サーバ名, portNum:ポート番号
// Success: Socket番号, Fault: Error番号
//**************************************************
int	AccessTo( char *ipAdd, int portNum )
{
struct hostent	*accessIP;		//接続先IP
struct sockaddr_in accessAddr;	//アクセスソケット
int	ret;
int	socketAccess;				//接続ソケット番号

 socketAccess = socket( AF_INET, SOCK_STREAM, 0 );    //接続用ソケットの生成
 if( socketAccess&0x80000000 ){ return( WIFI_SOCKET_ERROR ); }	

  // サーバのIPアドレスを検索します
  accessIP = gethostbyname( ipAdd );

  accessAddr.sin_family = AF_INET;
  accessAddr.sin_addr.s_addr = *( (unsigned long *)(accessIP->h_addr_list[0]) ); //IP設定
  accessAddr.sin_port = htons( portNum );	//ポート設定

 ret = connect( socketAccess, (struct sockaddr *)&accessAddr, sizeof(accessAddr) );
 if( ret!=0 ){
   closesocket( socketAccess );
   return( WIFI_CONNECT_ERROR );
  }
  return( socketAccess );
}

tcp通信でポートへの接続を待つ

デーモン側というかサーバ側というか、そんな感じです。

//**************************************************
// 指定された指定ポートにつなぎにくるソケットを待って接続します。
// portNum:ポート番号
// Success: Socket番号, Fault: Error番号
//**************************************************
int	WaitForAccess( int portNum ){
int	ret, i;
int	sockListen;					// 待受用ソケット
struct	sockaddr_in addrListen;
int	rc;
fd_set	fds;
struct	timeval tv;

int	socketAccess;				// 通信用ソケット
struct	sockaddr_in addrAccept;
int	cbAddrAccept;

 sockListen = socket( AF_INET, SOCK_STREAM, 0 );	// 待受用のソケット生成
 if( sockListen&0x80000000 ){ return( WIFI_SOCKET_ERROR ); }

 addrListen.sin_family = AF_INET;
 addrListen.sin_addr.s_addr = 0;		// 待受なので..0
 addrListen.sin_port = htons( portNum );	//ポート設定

 //ソケットをバインドする
 ret = bind( sockListen, (struct sockaddr *)&addrListen, sizeof(addrListen) );
 if( ret ){
    closesocket( sockListen );
    return( WIFI_BIND_ERROR );
 }

 ret = listen( sockListen, 1 );			//ポートを見に行く設定
 if( ret ){
    closesocket( sockListen );
    return( WIFI_LISTEN_ERROR );
 }

 ret = WIFI_TIMEOUT_ERROR;
 for( i=0; i<20; i++ ){
    FD_ZERO( &fds );		//ファイルディスクリプタの識別子初期化
    FD_SET( sockListen, &fds ); //sockListenのファイルディスクリプタ識別子に1をセット
    tv.tv_sec = 0;
    tv.tv_usec = 500L*1000L;	//待ち時間 : 500msで、20回(10sec)待つ

    //ポートの監視、(受信のみ監視、他はNULL)
    rc = select( (int)sockListen+1, &fds, NULL, NULL, &tv );

    if( FD_ISSET(sockListen,&fds) ){	//接続があった
        ret = 1;
        break;
    }
 }

 if( ret==WIFI_TIMEOUT_ERROR ){
    closesocket( sockListen );
    return( WIFI_TIMEOUT_ERROR );
 }

 //接続ソケットに対するソケット生成
 cbAddrAccept = sizeof( addrAccept );
 socketAccess = accept( sockListen, (struct sockaddr *)&addrAccept, &cbAddrAccept);

 if( socketAccess&0x80000000 ) {
    closesocket( sockListen );
    return( WIFI_ACCEPT_ERROR );
 }

 closesocket( sockListen );		//listenソケットのクローズ

 return( socketAccess );
}

WiFiのAPにつなげた2台のDSで、それぞれWaitForAccess()とAccessTo()を呼んでやれば、ソケットコネクションが張られて、ソケット番号が返ってきます。

このプログラムを使って、非同期に2台のDSでデータをやり取りするデモプログラムを作ってみました。もうちょっとデモらしくして公開してみようかなと思います。今は、お互いにボタンを送信し合う程度。

この接続ができるということは、ルータから外に出てインターネット経由で、DSがPeer to Peerで繋がるということなのでしょうか・・・?
んん、ということで、今日はこの辺で。

本当にやりたいことリスト

(ブログの終わりにやりたいことを書いておきたいと思います)

  • 求職活動・・・このブログで興味を持った人一声かけてください。m(_ _)m
  • Androidプログラム
  • Web系のプログラム