来自Socket的C ++ LibCurl GET

时间:2010-11-22 07:05:35

标签: c++ sockets curl libcurl

我想使用LibCurl将此代码(使用带有套接字扩展的脚本语言)转换为C ++。我之前只使用过一次LibCurl,所以对于我还需要什么,我有点不知所措。我的主要困惑在于我应该能够使用curl_easy_setopt(curl,CURLOPT_HTTPHEADER,header);要发送它,或者如果我需要解压缩套接字,那么就将其发送出来。

以下是脚本中的相关摘录...

public OnSocketConnected(Handle:socket, any:friendId) 
{
    decl String:CommunityId[32];
    FriendIDToCommunityId(friendId, CommunityId, sizeof(CommunityId));

    decl String:query[2048];
    decl String:cookieString[100];
    decl String:inviterString[32];
    decl String:groupString[32];

    GetConVarString(cookie, cookieString, sizeof(cookieString));
    GetConVarString(inviter, inviterString, sizeof(inviterString));
    GetConVarString(group, groupString, sizeof(groupString));


    Format(query, sizeof(query), "GET /actions/GroupInvite?type=groupInvite&inviter=%s&invitee=%s&group=%s HTTP/1.1\r\nHost: steamcommunity.com\r\nConnection: close\r\nCookie: steamLogin=%s\r\n\r\n", inviterString, CommunityId, groupString, cookieString);
    SocketSend(socket, query);
    LogMessage("%s", query);
}

这是我到目前为止在C ++中的用法。看起来我首先需要提取套接字,但我不熟悉网络编码,所以我不确定我需要从哪里开始。

void InviteToGroup(const char *szUserSteamID, const char *szInviterSteamID, const char *steamUser, const char *steamPass)
{
    CURL *curl;
    CURLcode res, result;
    //int sockfd; /* socket */
    char errorBuffer[CURL_ERROR_SIZE];

    const char *szUserID = GetCommunityID(szUserSteamID); // User's Steam Community ID
    const char *szInviterID = GetCommunityID(szInviterSteamID); // Inviter's Steam Community ID
    char *szGroupID = "";
    GetGroupCommunityID(1254745, &szGroupID); // Group Steam Community ID
    const char *szCookie = "76561198018111441%7C%7CC7D70E74A3F592F3E130CCF4CAACD4A7B9CAD993"; // Steam Community Login Cookie

    char *buffer = new char[512];

    // Create the GET request
    struct curl_slist *headers = NULL;
    headers = curl_slist_append(headers, "GET /actions/GroupInvite?type=groupInvite&inviter=");
    snprintf(buffer, sizeof(buffer), "%s&invitee=%s&group=%s ", szInviterID, szUserID, szGroupID);
    headers = curl_slist_append(headers, buffer);
    headers = curl_slist_append(headers, "HTTP/1.1\r\nHost: steamcommunity.com\r\nConnection: close\r\nCookie: ");
    snprintf(buffer, sizeof(buffer), "steamLogin=%s\r\n\r\n", szCookie);
    headers = curl_slist_append(headers, buffer);

    delete buffer;

    // Init CURL
    curl = curl_easy_init();

    if(curl)
    {
        curl_easy_setopt(curl, CURLOPT_URL, "https://www.steamcommunity.com");
        curl_easy_setopt(curl, CURLOPT_PORT, 443); // Check this before using
        curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorBuffer);
        //curl_easy_setopt(curl, CURLOPT_CONNECT_ONLY, 1); // No transfer, just extract the socket

        // Find out if we need to use Proxy stuff here

        char *userpass = new char[64];
        snprintf(userpass, sizeof(userpass), "%s:%s", steamUser, steamPass);
        curl_easy_setopt(curl, CURLOPT_USERPWD, userpass);
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);

        // Attempt to Connect the Steam Community Server
        res = curl_easy_perform(curl);

        if (res == CURLE_OK)
            Msg("Connected Successfully!\n");
        else
            Msg("Connection Failed! Error: %s\n", errorBuffer);

        // Close the connection
        curl_easy_cleanup(curl);
    }
}

1 个答案:

答案 0 :(得分:0)

因此,您的C ++不正确,这意味着您的代码将无效。

sizeof(char *)是指针的大小,而不是字符串的长度。因此,您的snprintf将在32位系统上打印最多4个字符,其中包含空终止符,因此您实际上只能获得长度为3的字符串。

如果您要使用“应该足够大”的缓冲区,请不要使用new分配它。如果你想使用snprintf,你可以使用std :: vector,然后检查snprintf的返回值,它是要写入的实际字符串的长度,然后在必要时增加缓冲区大小(返回值+ 1)。

vector<char> buffer;
size_t required = 511; 
do 
{ 
    buffer.resize( required + 1 );
    required = snprintf( &buffer[0], buffer.size(), formatstr, ... );
}
while( required >= buffer.size() );

没有必要在结尾处“释放”缓冲区(偶然你做错了),因为vector会自动执行此操作。

现在你将&amp; buffer [0]传递给函数,它将指向一个以null结尾的字符串,如果API需要char *而不是const char *,它将是可写的。 (libcurl虽然需要...作为curl_easy_setopt的第3个参数,所以你可以传入“任何东西”。因此你必须要小心,因为如果你不小心传入std :: string或者你不会被编译器警告的std ::向量)。