我正在创建一个Winamp插件,其功能是将通过HTTP播放的歌曲的详细信息发送到网页/网络服务器。我找不到真正有用的东西,所以决定第一次潜入C ++并自己动手。
该插件是一个C ++ DLL文件。每次播放新歌时我都可以将歌曲标题输出到Windows消息框(对于C ++的第一次定时器来说不错!))
我被困在哪里:
在找不到C ++方向的推送通知中,我找不到任何东西。
我尝试将HTTP库嵌入/包含在我的DLL中以尝试发布请求,但没有成功。 libcurl,这个library here和this library也是 - 但是无法让它们工作!我只是继续得到链接错误,然后一些。几个小时后,我就放弃了。
我是一个非常熟练的JavaScript程序员,所以我想也许使用JS连接到推送通知服务可以解决,但在C ++中运行JS对我来说太复杂了。也许我错了?
总而言之,我不知道哪种解决方案更好(阅读:更简单)实施 - 推送通知或发布请求?
我感谢任何解决方案/输入/指示/信息或任何你得到的。我可以发布代码,但我唯一的代码是从Winamp获取歌曲信息的部分,那部分可以工作。
提前致谢。
编辑:我想值得一提的是我正在使用新的VS2012?
答案 0 :(得分:2)
使用这些库是可以的,但是在谈到C ++时,我主要想到的是“纯代码”,所以我喜欢本地风格来做某事,而且没有图书馆的帮助就可以做到。
考虑到这一点,我可以使用Microsoft的winsock2库为您提供有关如何发送HTTP的POST请求的示例。
首先,我想指出我使用this link来了解如何使用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: %d\n", result);
return 0;
}
sockaddr_in sin;
int sock = socket(AF_INET, SOCK_STREAM, 0);
if(sock == INVALID_SOCKET)
{
//printf("Error at socket(): %ld\n", 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 host\n");
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: %ld\n", WSAGetLastError());
closesocket(sock);
WSACleanup();
return 0;
}
std::stringstream stream;
stream << "POST " << api << " HTTP/1.0\r\n"
<< "User-Agent: Mozilla/5.0\r\n"
<< "Host: " << hostname << "\r\n"
<< "Content-Type: application/x-www-form-urlencoded;charset=utf-8\r\n"
<< "Content-Length: " << strlen(parameters) << "\r\n"
<< "Accept-Language: en-US;q=0.5\r\n"
<< "Accept-Encoding: gzip, deflate\r\n"
<< "Accept: */*\r\n"
<< "\r\n" << parameters
;
if(send(sock, stream.str().c_str(), stream.str().length(), 0) == SOCKET_ERROR)
{
//printf("send failed: %d\n", WSAGetLastError());
closesocket(sock);
WSACleanup();
return 0;
}
if(shutdown(sock, SD_SEND) == SOCKET_ERROR)
{
//printf("shutdown failed: %d\n", WSAGetLastError());
closesocket(sock);
WSACleanup();
return 0;
}
char buffer[1];
do
{
result = recv(sock, buffer, 1, 0);
if(result > 0)
{
//printf("Bytes received: %d\n", result);
message += buffer[0];
}
else if(result == 0)
{
//printf("Connection closed\n");
}
else
{
//printf("recv failed: %d\n", WSAGetLastError());
}
}
while(result > 0);
closesocket(sock);
WSACleanup();
return 1;
}
当您使用DLL时,我注释掉了printf
,因此您可以根据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::string
以便将歌曲名称和艺术家安全地解析为POST POST消息字符串,您将需要知道如何操作,我推荐this link。