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系のプログラム