こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

Winsockについての質問

Winsockで、「GET / HTTP/1.1」というリクエストを「127.0.0.1(自分自身)」に送って(サーバーはAPACHE2)ドキュメントルートにある「index.html」を見る。
というプログラムを作ったのですが、受信ができません。

受信できるにはどうすればいいか教えてください。

尚以下がそのプログラムです。


#include<stdio.h>
#include<winsock2.h>



int main(){

SOCKET hsock;
struct sockaddr_in serverOption;
char buf[1024];
int Error;
int func_Error;

WSADATA wsadata;


func_Error=WSAStartup(MAKEWORD(2,0),&wsadata);


if(MAKEWORD(2,0)!=wsadata.wVersion){
fprintf( stderr, "Winsock version error\n");
return -1;
}

hsock=socket(AF_INET,SOCK_STREAM,0);


if(!hsock){
printf("ソケット作成エラー");
}


serverOption.sin_family=AF_INET;
serverOption.sin_addr.s_addr=inet_addr("210.81.150.5");
serverOption.sin_port=htonl(80);

func_Error=connect(hsock,(struct sockaddr *)&serverOption,sizeof(serverOption));


if(!func_Error){
printf("接続エラー");
}


func_Error=send(hsock,"GET / HTTP/1.1",strlen("GET / HTTP/1.1"),0);


if(!func_Error){
printf("データが送れない。残念ですた");
}


Error=recv(hsock,buf,sizeof(buf),0);



if( Error <= 0) {
printf("受信不可能");
return -1;
}


buf[Error]='\0';


printf("%s",buf);


closesocket(hsock);

WSACleanup();
return 0;

}

投稿日時 - 2005-10-09 15:11:41

QNo.1702195

困ってます

質問者が選んだベストアンサー

serverOption.sin_port=htonl(80);
       ↓
serverOption.sin_port=htons(80);

ポート番号(sin_port)は16ビットなので、質問文のプログラムでは80はhtonlで一度32ビット(00 00 00 80)に変換されてから、16ビット(00 00, 後ろ16ビットは切り捨て)に変換されてしまいます。
結果として0番ポートに接続しています。
htonsを使うようにしてください。


func_Error=send(hsock,"GET / HTTP/1.1",strlen("GET / HTTP/1.1"),0);
       ↓
func_Error=send(hsock,"GET / HTTP/1.1\n\n",strlen("GET / HTTP/1.1\n\n"),0);

HTTPでは空の行(改行のみ)が送られてくるまでは、リクエストが終了したとみなされないため、サーバーは何も送信してきません。


あとserverOptionは値を入れる前にmemsetなどで0で埋めておいたほうがいいです。

投稿日時 - 2005-10-09 20:47:42

お礼

質問に答えてくださり有難うございました。

おかげで、問題は解決できました。

投稿日時 - 2005-10-10 14:19:08

このQ&Aは役に立ちましたか?

1人が「このQ&Aが役に立った」と投票しています

回答(3)

ANo.2

RFC2068を見ると、以下のようになっています。

5.1 Request-Line
The Request-Line begins with a method token, followed by the
Request-URI and the protocol version, and ending with CRLF.


たぶん、送信コマンド末尾にCRLF がないからではないでしょうか?

"GET/HTTP/1.1" --> "GET/HTTP/1.1\r\n" に置き換えてみてください。

投稿日時 - 2005-10-09 19:22:53

お礼

質問に答えてくださりありがとう御座いました。

「GET/HTTP/1.1」の部分を直してみたいと思います。

投稿日時 - 2005-10-10 14:09:05

ANo.1

送信したあとすぐに受信しているためサーバーからデータを受信する前にrecvをコールしてエラーになっているんじゃないでしょうか。

投稿日時 - 2005-10-09 15:59:17

お礼

質問に答えてくださり有難う御座いました。

どうやらそれもあったようで、send関数を使った後に、printfを入れることで解決できました。

投稿日時 - 2005-10-10 14:21:07

あなたにオススメの質問