?? tracker.cpp
字號:
#include "Tracker.h"
#include <netdb.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include "Btcontent.h"
#include "Httpencode.h"
using namespace std;
const int INVALID_SOCK = -1;
const int T_CONNECTED = -1;
const int T_FREE = 0;
const int T_CONNECTING = 1;
const int T_READY = 2;
const int T_FINISHED = 3;
#define MAXHOSTNAMELEN 256
#define MAXPATHNAMELEN 1024
#define INFO_HASH_LEN 20
#ifndef DEBUG
#define DEBUG(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__)
#endif
btTracker TRACKER;
btTracker::btTracker()
{
m_sock = INVALID_SOCK;
m_listen_port = 6881;
m_status = T_FREE;
m_conn_refused = 0;
m_peers_count = 0;
m_seeds_count = 0;
m_tracker_count = 0;
m_tracker_active = 0;
m_f_started = 0;
m_f_stopped = 0;
m_f_completed = 0;
memset(m_tracker_id, 0, 21);
for(int i = 0; i < 10; i++)
{
m_sock_list[i] = INVALID_SOCK;
m_port_list[i] = 0;
m_stat_list[i] = T_FREE;
m_path_list[i] = NULL;
m_host_list[i] = NULL;
}
}
btTracker::~btTracker()
{
//close(m_sock);
char **p = m_host_list;
for(; *p; p++)
delete []*p;
p = m_path_list;
for(; *p; p++)
delete[]*p;
}
void btTracker::CloseSocket(int idx)
{
if(m_sock_list[idx] > 0)
close(m_sock_list[idx]);
m_sock_list[idx] = INVALID_SOCK;
m_stat_list[idx] = T_CONNECTED;
}
int btTracker::Reset()
{
}
int btTracker::Initial()
{
char **plist, *p, host[256], path[1024];
int i = 0, port;
plist = BTCONTENT.GetAnnounceList();
for(; plist && *plist; plist++)
{
if (Http_url_analyse(*plist, host, (int *) &port, path) < 0
|| (m_host_list[i] = new char [strlen(host) + 1]) == NULL
|| (m_path_list[i] = new char [strlen(path) + 1]) == NULL)
{
delete [] m_host_list[i];
delete [] m_path_list[i];
m_port_list[i] = -1;
continue;
}
strcpy(m_host_list[i], host);
m_port_list[i] = port;
strcpy(m_path_list[i], path);
if(i++ == 8)
break;
}
m_tracker_count = i;
for(int i = 0; i < m_tracker_count; i++)
{
cout<<m_host_list[i]<<endl;
cout<<m_path_list[i]<<endl;
cout<<m_port_list[i]<<endl;
}
char cnst[37] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
for (i = 0; i < 8; i++)
m_key[i] = cnst[random() % 36];
m_key[8] = '\0';
return 0;
}
int btTracker::s2sin(char *host, int port, sockaddr_in * paddr)
{
int n = 0;
bzero(paddr, sizeof(struct sockaddr_in));
port = htons(port);
paddr->sin_family = AF_INET;
paddr->sin_port = port;
if (NULL == host)
return -1;
struct hostent *p;
while(NULL == (p = gethostbyname(host)) && n++ < 5);
if(NULL == p)
return -1;
paddr->sin_family = p->h_addrtype;
memcpy(&(paddr->sin_addr), p->h_addr_list[0], sizeof(struct in_addr));
return 0;
}
int btTracker::Connect(int i)
{
struct sockaddr_in addr;
int ret;
printf("%s", "begin to connect...\n");
printf("HOST: %s\n",m_host_list[i]);
printf("PORT: %d\n",m_port_list[i]);
bzero(&addr,sizeof(addr));
if(s2sin(m_host_list[i], m_port_list[i], &addr) < 0
|| ((m_sock_list[i] = socket(AF_INET, SOCK_STREAM, 0)) < 0))
return -2;
printf("IP : %s\n",inet_ntoa(addr.sin_addr));
return connect_nonb(m_sock_list[i],&addr, sizeof(addr));
}
int btTracker::SendRequest(int idx, int mode)
{
char i_buff[3 * 20 + 1], p_buff[3 * 20 + 1], req_buffer[1024 * 2];
char *path, *host, *format, *event, tempath[1024];
char *pevent[] = { "started", "stopped", "completed" };
size_t len;
int port;
path = m_path_list[idx];
host = m_host_list[idx];
port = m_port_list[idx];
if(NULL == req_buffer || NULL == path || NULL == host || !port)
return -1;
if (!mode)
event = pevent[0];
if (strchr(path, '?'))
format = REQ_URL_P1A_FMT;
else
format = REQ_URL_P1_FMT;
if (snprintf(tempath, MAXPATHNAMELEN, format,
(char *) path,
Http_url_encode(i_buff, (char *) BTCONTENT.GetInfoHash(), 20),
Http_url_encode(p_buff,(char *) BTCONTENT.GetPeerId(),20),
81,
(char *) m_key) > MAXPATHNAMELEN)
return -1;
if (event) {
if (snprintf(req_buffer, MAXPATHNAMELEN, REQ_URL_P2_FMT,
tempath,
(unsigned long long) 0,
(unsigned long long) 0,
(unsigned long long) BTCONTENT.GetLeftBytes(),
event, 100) > 1024)
return -1;
}
else
{
if (snprintf(req_buffer, MAXPATHNAMELEN, REQ_URL_P3_FMT,
tempath,
(unsigned long long) 0,
(unsigned long long) 0,
(unsigned long long) BTCONTENT.GetLeftBytes(),
100) > 1024)
return -1;
}
if (*m_tracker_id && MAXPATHNAMELEN - strlen(req_buffer)
> 11 + strlen(m_tracker_id))
strcat(strcat(req_buffer, "&trackerid="), m_tracker_id);
struct sockaddr_in addr;
if (Ip2sin(host, port, &addr) < 0)
{
char req_host[MAXHOSTNAMELEN];
if (snprintf(req_host, MAXHOSTNAMELEN,
"\r\nHost: %s", host) > MAXHOSTNAMELEN)
return -1;
strcat(req_buffer, req_host);
}
strcat(req_buffer, "\r\nUser-Agent: ");
strcat(req_buffer, "Bittorrent");
strcat(req_buffer, "\r\nAccept: */*");
strcat(req_buffer, "\r\nAccept-Encoding: gzip");
strcat(req_buffer, "\r\nConnection: closed");
strcat(req_buffer, "\r\n\r\n");
cout<<req_buffer<<endl;
if( (len = write(m_sock_list[idx], req_buffer, strlen(req_buffer)))
> 0)
{
}
return 0;
}
int btTracker::writen(int fd, const void *vptr, size_t len)
{
size_t nleft;
ssize_t nwrite;
const char *ptr;
ptr = (const char *) vptr;
nleft = len;
while (nleft) {
if ( (nwrite = write(fd, vptr, len)) <= 0) {
if (nwrite < 0 && errno == EINTR)
nwrite = 0;
else
return -1;
}
nleft -= nwrite;
ptr += nwrite;
}
return len;
}
int btTracker::readn(int fd, char* buffer, size_t len)
{
size_t nread;
int n;
char* ptr;
ptr = buffer;
nread = 0;
while(len)
{
if( (n = read(fd, ptr, len - n)) <= 0)
if(n < 0 && errno == EINTR)
continue;
else
break;
nread += n;
len -= n;
ptr += n;
}
}
int btTracker::Ip2sin(char *h, int p, struct sockaddr_in *psin)
{
psin->sin_family = AF_INET;
psin->sin_port = htons(p);
psin->sin_addr.s_addr = inet_addr(h);
return psin->sin_addr.s_addr == htonl(INADDR_NONE) ? -1 : 0;
}
//return if connected: 0, connecting : -1 , error : -2
int btTracker::connect_nonb(int sockfd, struct sockaddr_in *saptr,
socklen_t salen)
{
int flags, n;
if ((flags = fcntl(sockfd, F_GETFL, 0) < 0)
|| fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) < 0)
return -2;
if ((n = connect(sockfd, (struct sockaddr *) saptr, salen)) < 0)
{
if (errno == EINPROGRESS)
{
printf("%s\n","is connecting...");
return -1;
}
else
{
printf("%s\n", "can not be connected");
return -2;
}
}
else
return 0;
}
int btTracker::SocketReady(fd_set* rset, fd_set* wset, int* nfds, fd_set* next_rset, fd_set* next_wset)
{
int i, n, ret, nactive = 0, maxfd = -1;
char* buff[1024];
for(i = 0; i < m_tracker_count;)
{
DEBUG("Host : %s\n", m_host_list[i]);
if(T_CONNECTED == m_stat_list[i])
DEBUG("%s\n", "STATE : T_CONNECTED");
else
{
if(INVALID_SOCK != m_sock_list[i]
&& FD_ISSET(m_sock_list[i], rset))
DEBUG("%s\n", "read is set");
if(INVALID_SOCK != m_sock_list[i]
&& FD_ISSET(m_sock_list[i], wset))
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -