接続プログラムの試作
図書館というものがあったことを思い出して,WinSock2の解説書を借りてきた.むやみに買う前に思い出せばよかった・・・
WinSock2プログラミング―Windows Sockets APIによるネットワークプログラミングのすべて
- 作者: ルイスナッパー,Lewis Napper,江村豊,トップスタジオ
- 出版社/メーカー: ソフトバンククリエイティブ
- 発売日: 2004/12
- メディア: 単行本
- クリック: 31回
- この商品を含むブログ (16件) を見る
ぎゃああああああ.
まず,recv()で受け取ったデータには終端文字列が付いていなかったようだ.そのせいで,前に受け取ったメッセージの残りとか,データが未定義の部分まで表示されている.終端文字列は確かGTPの仕様で使われていないので,ちゃんと処理しなければいけなかった.
そして,ログイン成功後,GTPコマンドが送信されてこないのでrecv()のところでずっとデータを待ち続け(ブロッキングと言うようだ),処理が帰ってこなくなった.危険すぎる.
別ルート(人用クライアント)で接続して,ログインまではできている事は確認した.(kgsGtp経由でログインすると名前の横にアイコンが付く)
さて,本に従って次はブロッキングが起きないような形にしていこう.
今回のコード
#include<stdio.h> #include<winsock2.h> int main(int argc, char **argv) { WORD versionRequested = MAKEWORD(1,1); WSADATA dllWSAData; int ResultCode; /*ws2_32.dllの初期化*/ ResultCode = WSAStartup(versionRequested,&dllWSAData); if(ResultCode != 0) { fprintf(stderr,"WSAStartup() error\n"); WSACleanup(); return 0; } /*WinSockのバージョンが要求と異なったら終了*/ if(dllWSAData.wVersion != versionRequested) { fprintf(stderr,"requested version doesn't be supported\n"); WSACleanup(); return 0; } /*ソケットの作成と確認*/ SOCKET sock_kgsGtp = socket(AF_INET,SOCK_STREAM,0); if(sock_kgsGtp == INVALID_SOCKET) { fprintf(stderr,"socket() failed\n"); WSACleanup(); return 0; } /*ソケットアドレスの設定*/ struct in_addr addr_serv; addr_serv.s_addr=inet_addr("127.0.0.1"); struct sockaddr_in sa_kgsGtp; sa_kgsGtp.sin_family = AF_INET; sa_kgsGtp.sin_port=htons(65535); sa_kgsGtp.sin_addr=addr_serv; /*kgsGtpへ接続*/ ResultCode = connect(sock_kgsGtp,(LPSOCKADDR)&sa_kgsGtp,sizeof(SOCKADDR)); if(ResultCode == SOCKET_ERROR) { fprintf(stderr,"connect error\n"); WSACleanup(); return 0; } /*GTPコマンドの受信と送信ループ*/ char msg_recv[256]; char msg_send[256]; int flag_communicate = 1; while(flag_communicate == 1) { /* 9/13 ログイン成功後にコマンドが送られてこないのでrecv()で止まる*/ recv(sock_kgsGtp,msg_recv,sizeof(msg_recv),0); fprintf(stdout,"%s\n",msg_recv); strcpy_s(msg_send,256,"?\n\n"); send(sock_kgsGtp,msg_send,strlen(msg_send),0); } /*通信の終了*/ shutdown(sock_kgsGtp,SD_BOTH); closesocket(sock_kgsGtp); WSACleanup(); return 0; }