C++ &引用;在此服务器上找不到请求的URL/公告;bittorrent HTTP请求出错

C++ &引用;在此服务器上找不到请求的URL/公告;bittorrent HTTP请求出错,c++,http,bittorrent,C++,Http,Bittorrent,我正在尝试向bittorrent tracker服务器发出HTTP请求以获取对等列表 #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> // for gethostbyname() #include <errno.h> #include <stdio.h> #include <string

我正在尝试向bittorrent tracker服务器发出HTTP请求以获取对等列表

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>  // for gethostbyname()
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <iostream>
using namespace std;

struct in_addr *atoaddr( const char* address)
{
static struct hostent *host;
static struct in_addr saddr;

// First try nnn.nnn.nnn.nnn form
saddr.s_addr = inet_addr(address);
if (saddr.s_addr != -1)
    return &saddr;

host = gethostbyname(address);
if( host )
    return (struct in_addr *) *host->h_addr_list;

return 0;
}

int main(){
int numbytes=0;
int m_Port=80;
string m_Host="torrent.ubuntu.com";
int m_Sock;
struct hostent *host;
static struct in_addr saddr;
string buffer;
char* buf;

//HTTP request string
buffer.append("GET http://torrent.ubuntu.com:6969/announce HTTP/1.1\r\n");
buffer.append("Host: torrent.ubuntu.com\r\n");
buffer.append("Accept-Encoding: identity\r\n");
buffer.append("info_hash: %36%be%21%35%ab%cc%f4%03%2f%bb%28%bb%1b%0d%4f%da%f7%49%f8%58\r\n");
buffer.append("peer_id: ABCDEFGHIJKLMNOPQRST\r\n");
buffer.append("port: 6881\r\n");
buffer.append("compact: 1\r\n");
buffer.append("uploaded: 0\r\n");
buffer.append("downloaded: 0\r\n");
buffer.append("left: 987758592\r\n");
buffer.append("event: started\r\n");
buffer.append("\r\n");

in_addr* addr = atoaddr( m_Host.c_str() );
if( !addr )
{
    cout<<"Error address\n";
    return 1;
}

sockaddr_in address;
memset( (char*)&address, 0, sizeof(address) );
address.sin_family = AF_INET;
address.sin_port = htons( m_Port );
address.sin_addr.s_addr = addr->s_addr;

m_Sock = socket( AF_INET, SOCK_STREAM, 0 );
if(m_Sock<0){
    cout<<"Socket error\n";
    return 1;
}

if( ::connect( m_Sock, (sockaddr const*)&address, sizeof(address) ) < 0 )
{
    cout<<"connect error";
    return 1;
}

buf = (char*)buffer.c_str();
numbytes = buffer.length();
while( numbytes > 0 )
{
    int n = ::send( m_Sock, buf, buffer.size(), 0 );
    std::cout<<"\n\n--HTTP request:\n"<<buf<<std::endl;
    if( n<0 )
    {
        cout<<"number of bytes sent <0\n";
        return 1;
    }
    numbytes -= n;
    buf += n;
}

cout<<"\ngetting response: \n";
unsigned char recvBuf[ 2048 ];
int a;
do{
    a = recv( m_Sock, (char*)recvBuf, sizeof(recvBuf), 0 );
    fwrite(recvBuf, 1, a, stdout);
}while(a!=0);

if(m_Sock>0)
    close(m_Sock);

return 0;
}

这就是我希望在从我的C代码发出请求时看到的。我做错了什么?

我相信您的代码失败是因为您犯了一个小错误:您不应该将套接字连接到端口80,而应该连接到端口6969,然后发送
GET/announce
查询,而不是在
GET
方法中发送完整的URL。

我使用了Wireshark(感谢一位老朋友的建议)用于获取邮递员发送的请求。 以下是对我有用的代码:

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>  // for gethostbyname()
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <iostream>
using namespace std;

// Try to work out address from string
// returns 0 if bad
struct in_addr *atoaddr( const char* address) 
{
static struct hostent *host;
static struct in_addr saddr;

// First try nnn.nnn.nnn.nnn form
saddr.s_addr = inet_addr(address);
if (saddr.s_addr != -1)
    return &saddr;

host = gethostbyname(address);
if( host )
    return (struct in_addr *) *host->h_addr_list;

return 0;
}

int main(){
int numbytes=0;
int m_Port=6969;
string m_Host="torrent.ubuntu.com";
int m_Sock;
struct hostent *host;
static struct in_addr saddr;
string buffer;
char* buf;

//  HTTP request string

//  buffer.append("GET /announce HTTP/1.1\r\n");
//  buffer.append("Host: torrent.ubuntu.com:6969\r\n");
//  buffer.append("Accept-Encoding: identity\r\n");
//  buffer.append("info_hash:     %36%be%21%35%ab%cc%f4%03%2f%bb%28%bb%1b%0d%4f%da%f7%49%f8%58\r\n");
//  buffer.append("peer_id: ABCDEFGHIJKLMNOPQRST\r\n");
//  buffer.append("port: 6881\r\n");
//  buffer.append("uploaded: 0\r\n");
//  buffer.append("downloaded: 0\r\n");
//  buffer.append("left: 987758592\r\n");
//  buffer.append("compact: 1\r\n");
//  buffer.append("event: started\r\n");
buffer.append("GET /announce?info_hash=%36%be%21%35%ab%cc%f4%03%2f%bb%28%bb%1b%0d%4f%da%f7%49%f8%58&"
        "peer_id=ABCDEFGHIJKLMNOPQRST&"
        "port=6881&"
        "compact=1&"
        "uploaded=0&"
        "downloaded=0&"
        "left=987758592&"
        "event=started HTTP/1.1\r\n");
buffer.append("\r\n");

in_addr* addr = atoaddr( m_Host.c_str() );
if( !addr )
{
    cout<<"Error address\n";
    return 1;
}

sockaddr_in address;
memset( (char*)&address, 0, sizeof(address) );
address.sin_family = AF_INET;
address.sin_port = htons( m_Port );
address.sin_addr.s_addr = addr->s_addr;

m_Sock = socket( AF_INET, SOCK_STREAM, 0 );
if(m_Sock<0){
    cout<<"Socket error\n";
    return 1;
}

if( ::connect( m_Sock, (sockaddr const*)&address, sizeof(address) ) < 0 )
{
    cout<<"connect error";
    return 1;
}

buf = (char*)buffer.c_str();
numbytes = buffer.length();
while( numbytes > 0 )
{
    int n = ::send( m_Sock, buf, buffer.size(), 0 );
    std::cout<<"\n\n--HTTP request:\n"<<buf<<std::endl;
    if( n<0 )
    {
        cout<<"number of bytes sent <0\n";
        return 1;
    }
    numbytes -= n;
    buf += n;
}

cout<<"\ngetting response: \n";
unsigned char recvBuf[ 2048 ];
int a;
do{
    a = recv( m_Sock, (char*)recvBuf, sizeof(recvBuf), 0 );
    fwrite(recvBuf, 1, a, stdout);
}while(a!=0);
cout<<"\n";

if(m_Sock>0)
    close(m_Sock);

return 0;
}
#包括
#包括
#包括
#包含//用于gethostbyname()
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
//尝试从字符串中算出地址
//如果错误,则返回0
_addr*atoaddr中的结构(常量字符*地址)
{
静态结构主机*主机;
静态结构在地址中;
//先试试nnn.nnn.nnn.nnn表格
saddr.s_addr=inet_addr(地址);
如果(saddr.s_addr!=-1)
返回&saddr;
主机=gethostbyname(地址);
如果(主机)
返回(struct in_addr*)*host->h_addr_列表;
返回0;
}
int main(){
int numbytes=0;
int m_端口=6969;
字符串m_Host=“torrent.ubuntu.com”;
int m_袜子;
结构主机*主机;
静态结构在地址中;
字符串缓冲区;
char*buf;
//HTTP请求字符串
//append(“获取/宣布HTTP/1.1\r\n”);
//append(“主机:torrent.ubuntu.com:6969\r\n”);
//append(“接受编码:标识\r\n”);
//缓冲区。追加(“信息散列:%36%be%21%35%ab%cc%f4%03%2f%bb%28%bb%1b%0d%4f%da%f7%49%f8%58\r\n”);
//append(“peer_id:ABCDEFGHIJKLMNOPQRST\r\n”);
//buffer.append(“端口:6881\r\n”);
//buffer.append(“上载:0\r\n”);
//buffer.append(“已下载:0\r\n”);
//buffer.append(“左:987758592\r\n”);
//buffer.append(“compact:1\r\n”);
//buffer.append(“事件:已启动\r\n”);
buffer.append(“GET/announce?info_hash=%36%be%21%35%ab%cc%f4%03%2f%bb%28%bb%1b%0d%4f%da%f7%49%f8%58&”
“peer_id=ABCDEFGHIJKLMNOPQRST&”
“端口=6881&”
“紧凑型=1&”
“上传=0&”
“已下载=0&”
“左=987758592&”
“事件=已启动HTTP/1.1\r\n”);
buffer.append(“\r\n”);
in_addr*addr=atoaddr(m_Host.c_str());
如果(!addr)
{

我相信您只需要在
GET
行中指定路径,因此:
GET/announcehttp/1.1\r\n
而不是完整的URL。我也尝试了。我得到了相同的响应。我认为您的问题在于连接端口。您应该连接到端口6969,而不是代码中显示的端口80(变量
m_port
)。此外,正如@Kninnug所告诉的,您应该发送
GET/announce HTTP/1.1\r\n
,而不是完整的URL。现在我得到了“HTTP/1.0 400错误请求内容长度:34内容类型:text/plain您发送给我的垃圾-无信息散列”我验证了我的信息散列,它就在那里:
d8:completei12e10:incompletei1e8:intervali1800e5:peers18:[�_�����4&N=;8��e
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>  // for gethostbyname()
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <iostream>
using namespace std;

// Try to work out address from string
// returns 0 if bad
struct in_addr *atoaddr( const char* address) 
{
static struct hostent *host;
static struct in_addr saddr;

// First try nnn.nnn.nnn.nnn form
saddr.s_addr = inet_addr(address);
if (saddr.s_addr != -1)
    return &saddr;

host = gethostbyname(address);
if( host )
    return (struct in_addr *) *host->h_addr_list;

return 0;
}

int main(){
int numbytes=0;
int m_Port=6969;
string m_Host="torrent.ubuntu.com";
int m_Sock;
struct hostent *host;
static struct in_addr saddr;
string buffer;
char* buf;

//  HTTP request string

//  buffer.append("GET /announce HTTP/1.1\r\n");
//  buffer.append("Host: torrent.ubuntu.com:6969\r\n");
//  buffer.append("Accept-Encoding: identity\r\n");
//  buffer.append("info_hash:     %36%be%21%35%ab%cc%f4%03%2f%bb%28%bb%1b%0d%4f%da%f7%49%f8%58\r\n");
//  buffer.append("peer_id: ABCDEFGHIJKLMNOPQRST\r\n");
//  buffer.append("port: 6881\r\n");
//  buffer.append("uploaded: 0\r\n");
//  buffer.append("downloaded: 0\r\n");
//  buffer.append("left: 987758592\r\n");
//  buffer.append("compact: 1\r\n");
//  buffer.append("event: started\r\n");
buffer.append("GET /announce?info_hash=%36%be%21%35%ab%cc%f4%03%2f%bb%28%bb%1b%0d%4f%da%f7%49%f8%58&"
        "peer_id=ABCDEFGHIJKLMNOPQRST&"
        "port=6881&"
        "compact=1&"
        "uploaded=0&"
        "downloaded=0&"
        "left=987758592&"
        "event=started HTTP/1.1\r\n");
buffer.append("\r\n");

in_addr* addr = atoaddr( m_Host.c_str() );
if( !addr )
{
    cout<<"Error address\n";
    return 1;
}

sockaddr_in address;
memset( (char*)&address, 0, sizeof(address) );
address.sin_family = AF_INET;
address.sin_port = htons( m_Port );
address.sin_addr.s_addr = addr->s_addr;

m_Sock = socket( AF_INET, SOCK_STREAM, 0 );
if(m_Sock<0){
    cout<<"Socket error\n";
    return 1;
}

if( ::connect( m_Sock, (sockaddr const*)&address, sizeof(address) ) < 0 )
{
    cout<<"connect error";
    return 1;
}

buf = (char*)buffer.c_str();
numbytes = buffer.length();
while( numbytes > 0 )
{
    int n = ::send( m_Sock, buf, buffer.size(), 0 );
    std::cout<<"\n\n--HTTP request:\n"<<buf<<std::endl;
    if( n<0 )
    {
        cout<<"number of bytes sent <0\n";
        return 1;
    }
    numbytes -= n;
    buf += n;
}

cout<<"\ngetting response: \n";
unsigned char recvBuf[ 2048 ];
int a;
do{
    a = recv( m_Sock, (char*)recvBuf, sizeof(recvBuf), 0 );
    fwrite(recvBuf, 1, a, stdout);
}while(a!=0);
cout<<"\n";

if(m_Sock>0)
    close(m_Sock);

return 0;
}