Winsock2 を使用して HTTP プロトコルを試しています。私は機能に取り組んでいます
int recv_data(const char *hostname, char *resp);
この関数は、特定のホストに HTTP HEAD リクエストを送信し、レスポンスを受信することを目的としています。ポインター resp にメモリを割り当て、そこに応答をコピーしてから、受信した応答の合計バイト数を返します。
これが私の受信ループです:
int recv_data(const char *hostname, char *resp)
{
int totalRecvd = 0;
stringstream sStream;
while (true)
{
char buffer[MAX_HEADER_SIZE];
int retValue = recv(s, buffer, MAX_HEADER_SIZE, 0);
if (retValue == 0)
break; // connection has been closed
else if (retValue == SOCKET_ERROR)
throw RecvException("http_headreq() unable to receive data");
else //
{
buffer[retValue] = 0; // append null terminator
sStream << buffer; // dump buffer into stream
totalRecvd += retValue + 1; // tally received bytes
}
}
/** Allocate and read entire read stream into memory */
resp = new char[totalRecvd + 1];
strcpy(resp, sStream.str().c_str());
return totalRecvd);
}
これはすべて正常に機能し、この時点で resp を出力すると、正常に出力されます。関数が明らかに戻った後に resp を出力しようとすると、問題が発生します。これが通常のやり方であるとは思いません。もし私が間違っていなければ、stringstream を使用して応答を一時的に保存することに関係があると思います。stringstream が収集するデータが範囲外になることについてどこかで読んだことがあると思います。
この関数をこのように設定して、呼び出し元が char* を渡すだけで、関数が正しい量のメモリを割り当てることができることを期待していました (これは、ホストとによって返されるバイト数に応じて実行時に決定されます)。関数が戻り、stringstream が範囲外になった後、ポインターが不良である char 配列として、メモリ内の stringstream から永続的なコピーを取得する方法はありますか?
[編集]: これが私の問題に組み込まれた以下に投稿された解決策です。これを Winsock2 proramming に再利用しようとしている人は誰でもうまくいくようです。recv() が 0 を返すと、接続が閉じられるまでサーバーからデータを受信します。 new 演算子がポインターを変更し、渡されない限り、関数が戻った後にその変更が反映されないため、ソリューションはポインターへの参照を渡します。参考までに。
int recv_data(SOCKET s, char *&data)
{
int totalRecvd = 0;
std::stringstream sStream;
while (true)
{
char buffer[MAX_HEADER_SIZE];
int retValue = recv(s, buffer, MAX_HEADER_SIZE, 0);
if (retValue == 0)
break; // connection has been closed
else if (retValue == SOCKET_ERROR)
throw RecvException("http_headreq() unable to receive data");
else //
{
buffer[retValue] = 0; // append null terminator
sStream << buffer; // dump buffer into stream
totalRecvd += retValue + 1; // tally received bytes
}
}
/** Allocate and read entire read stream into memory */
data = new char[totalRecvd + 1];
strcpy_s(data, totalRecvd, sStream.str().c_str());
data[totalRecvd] = 0;
return totalRecvd;
}