在DLL中使用的最简单的C++PUSH通知/POST解决方案

Most simple C++ PUSH notification / POST solution to use inside a DLL?

本文关键字:通知 POST 解决方案 C++PUSH 最简单 DLL      更新时间:2023-10-16

我正在制作一个Winamp插件,其唯一功能是通过HTTP将正在播放的歌曲的详细信息发送到网页/网络服务器。我找不到像这样真正有效的东西,所以我决定第一次深入到C++中,自己动手。

该插件是一个C++DLL文件。我已经到了每次播放新歌时都可以将歌曲标题输出到窗口消息框的地步(对于C++第一个计时器来说还不错!;)

我被困在哪里:

在C++方向的推送通知中,我根本找不到任何可以让我使用的东西。

我尝试将HTTP库嵌入/包含到我的DLL中,以尝试发布请求,但没有成功。libcurl,这里的这个库,还有这个库——但它们都无法工作!我只是不断地得到链接错误,然后一些。几个小时后我就放弃了。

我是一个非常熟练的JavaScript程序员,所以我想也许使用JS连接到推送通知服务是可行的,但在C++中运行JS对我来说太复杂了。也许我错了?

总而言之,我不知道哪种解决方案更容易实现——推送通知还是发布请求?

我感谢您提供的任何解决方案/意见/指导/信息或任何信息。我可以发布代码,但我唯一的代码是从Winamp获得歌曲信息的部分,这部分有效。

提前谢谢。

编辑:我想值得注意的是,我正在使用新的VS2012

使用这类库是可以的,但当谈到C++时,我主要想到的是"纯代码",所以我喜欢原生风格来做一些事情,并且在没有库的帮助下完成。

考虑到这一点,我可以为您提供一个关于如何使用Microsoft的winsock2库发送HTTP的POST请求的示例。

首先,我想指出,我使用这个链接是为了了解如何使用winsock2.h

好的,现在转到代码,你需要这些包括:

#include <string>
#include <sstream>
#include <winsock2.h>

您还需要链接winsock2库(或在您使用VS2012时在项目设置中指定它):

#pragma comment(lib, "ws2_32.lib")

现在,我从链接中编辑的函数(我只是编辑了它,使它看起来更简单,还做了一些错误检查和适当的清理):

int http_post(char *hostname, char *api, char *parameters, std::string& message)
{
    int result;
    WSADATA wsaData;
    result = WSAStartup(MAKEWORD(1, 1), &wsaData);
    if(result != NO_ERROR)
    {
        //printf("WSAStartup failed: %dn", result);
        return 0;
    }
    sockaddr_in sin;
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    if(sock == INVALID_SOCKET)
    {
        //printf("Error at socket(): %ldn", WSAGetLastError());
        WSACleanup();
        return 0;
    }
    sin.sin_family = AF_INET;
    sin.sin_port = htons(80);
    struct hostent *host_addr = gethostbyname(hostname);
    if(host_addr == NULL)
    {
        //printf("Unable to locate hostn");
        closesocket(sock);
        WSACleanup();
        return 0;
    }
    sin.sin_addr.s_addr = *((int *)*host_addr->h_addr_list);
    if(connect(sock, (const struct sockaddr *)&sin, sizeof(sockaddr_in)) == SOCKET_ERROR)
    {
        //printf("Unable to connect to server: %ldn", WSAGetLastError());
        closesocket(sock);
        WSACleanup();
        return 0;
    }
    std::stringstream stream;
    stream << "POST " << api << " HTTP/1.0rn"
           << "User-Agent: Mozilla/5.0rn"
           << "Host: " << hostname << "rn"
           << "Content-Type: application/x-www-form-urlencoded;charset=utf-8rn"
           << "Content-Length: " << strlen(parameters) << "rn"
           << "Accept-Language: en-US;q=0.5rn"
           << "Accept-Encoding: gzip, deflatern"
           << "Accept: */*rn"
           << "rn" << parameters
    ;
    if(send(sock, stream.str().c_str(), stream.str().length(), 0) == SOCKET_ERROR)
    {
        //printf("send failed: %dn", WSAGetLastError());
        closesocket(sock);
        WSACleanup();
        return 0;
    }
    if(shutdown(sock, SD_SEND) == SOCKET_ERROR)
    {
        //printf("shutdown failed: %dn", WSAGetLastError());
        closesocket(sock);
        WSACleanup();
        return 0;
    }
    char buffer[1];
    do
    {
        result = recv(sock, buffer, 1, 0);
        if(result > 0)
        {
            //printf("Bytes received: %dn", result);
            message += buffer[0];
        }
        else if(result == 0)
        {
            //printf("Connection closedn");
        }
        else
        {
            //printf("recv failed: %dn", WSAGetLastError());
        }
    }
    while(result > 0);
    closesocket(sock);
    WSACleanup();
    return 1;
}

当您使用DLL时,我注释掉了printf s,因此您可以根据Winamp插件API使用适当的输出函数。

现在,使用这个函数,它是不言自明的:

std::string post;
http_post("www.htmlcodetutorial.com", "/cgi-bin/mycgi.pl", "user=example123&artist=The Beatles&music=Eleanor Rigby", post);

通过这样做,并检查函数返回编号(1表示成功,0表示失败),您可以解析从站点返回的结果字符串,并检查是否一切正常

关于你的最后一个问题,使用POST请求是可以的,但作为一名网站管理员,你知道有可能"滥用"这个选项,比如请求淹没等。但这确实是最简单的方法。

如果您在服务器端正确解析数据,并检查请求是否有任何不当使用,那么您就可以毫无问题地使用此方法。

最后,作为C++初学者,您需要知道如何操作std::strings,以便安全地将歌曲名称和艺术家解析为post后消息字符串,如果您还不知道,我推荐使用此链接。