BitTorrent 协议规范(BT协议集合)四

矩形口径喇叭天线设计——参数设置 我们建立好矩形口径喇叭天线的模型后(模型建立可参考B站相关视频或者李明洋的《HFSS天线设计》),如何修改参数达到我们的指标呢? 阅读详情

通常BT客户端每几分钟就要向tracker发送一次请求.对于一些比较大的BT站点,其tracker的压力是可想而知的.降低tracker的压力首先考虑到的当然是采用更低网络开销的udp协议.于是Bittorrent udp-tracker protocol应运而生.
  这个协议很简单.
  下面是实现它的封装类: 

 

// UDPTrackerClient.h: interface for the CUDPTrackerClient class. 
// 
////////////////////////////////////////////////////////////////////// 

#if !defined(AFX_UDPTRACKERCLIENT_H__69B6ACC8_8193_4680_81D8_925B1550E92C__INCLUDED_) 
#define AFX_UDPTRACKERCLIENT_H__69B6ACC8_8193_4680_81D8_925B1550E92C__INCLUDED_ 

#if _MSC_VER > 1000 
#pragma once 
#endif // _MSC_VER > 1000 

#include <WINSOCK2.H> 
#pragma comment(lib, "ws2_32.lib") 

#ifndef _DISABLEWARNING4786_4355 
#define _DISABLEWARNING4786_4355 
#pragma warning( disable : 4786 ) 
#pragma warning( disable : 4355 ) 
#endif 
#ifndef _ENABLEUSESTL 
#define _ENABLEUSESTL 
#include <LIST> 
#include <SET> 
#include <VECTOR> 
#include <QUEUE> 
#include <STRING> 
#include <MAP> 
using namespace std; 
#endif 

class CPeerHostInfo 
{ 
public:     
DWORD IP;
//节点IP 
WORD Port;//节点端口 
}; 
class CUDPTrackerClient 
{ 
public: 
CUDPTrackerClient(); 
virtual ~CUDPTrackerClient(); 
void CancelSocketOperate(); 
BOOL Connect(
const char * szServer,WORD wPort = 0); 
DWORD Announcing(BYTE
* pInfoHash,BYTE * pPeerID, 
__int64 idownloaded,__int64 ileft,__int64 iuploaded, 
int ievent, 
DWORD dwIP,WORD wPort); 

BOOL Disconnect(); 
public: 
SOCKET   m_socket; 
DWORD   m_dwIP; 
WORD   m_wPort; 
__int64   m_iConnection_id; 
DWORD   m_dwConnectTick; 
string   m_strError; //如果请求失败,此变量保存错误信息 
DWORD m_dwDonePeers; //种子数 
DWORD m_dwNumPeers; //当前下载者个数 
DWORD m_dwInterval; //查询间隔时间 
list m_listPeers; 
}; 

#endif // !defined(AFX_UDPTRACKERCLIENT_H__69B6ACC8_8193_4680_81D8_925B1550E92C__INCLUDED_) 
// UDPTrackerClient.cpp: implementation of the CUDPTrackerClient class. 
// 
////////////////////////////////////////////////////////////////////// 

#include 
"stdafx.h" 
#include 
"UDPTrackerClient.h" 

#include 
"DataStream.h" 
#ifdef _DEBUG 
#undef THIS_FILE 
static char THIS_FILE[]=__FILE__; 
#define new DEBUG_NEW 
#endif 

////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
#define RECVBUFSIZE 2048 

CUDPTrackerClient::CUDPTrackerClient() 
{ 
m_socket 
= INVALID_SOCKET; 
m_iConnection_id 
= 0; 
m_dwConnectTick 
= 0; 
m_dwIP 
= 0; 
m_wPort 
= 0; 
m_dwDonePeers 
= 0; //种子数 
m_dwNumPeers = 0; //当前下载者个数 
m_dwInterval = 0; //查询间隔时间 
} 

CUDPTrackerClient::
~CUDPTrackerClient() 
{ 
Disconnect(); 

} 
void CUDPTrackerClient::CancelSocketOperate() 
{ 
if(m_socket != INVALID_SOCKET) 
{ 
LINGER lingerStruct;    
// If we're supposed to abort the connection, set the linger value 
// on the socket to 0.    
lingerStruct.l_onoff = 1; 
lingerStruct.l_linger 
= 0; 
setsockopt(m_socket, SOL_SOCKET, SO_LINGER, 
  (
char *)&lingerStruct, sizeof(lingerStruct) ); 
} 
} 
BOOL CUDPTrackerClient::Disconnect() 
{ 
m_iConnection_id 
= 0; 
m_dwDonePeers 
= 0; //种子数 
m_dwNumPeers = 0; //当前下载者个数 
m_dwInterval = 0; //查询间隔时间 
if ( m_socket != INVALID_SOCKET ) 
{ 
m_dwIP 
= 0; 
m_wPort 
= 0; 
// Now close the socket handle. This will do an abortive or 
// graceful close, as requested.     
shutdown(m_socket,SD_BOTH); 
closesocket(m_socket); 
m_socket 
= INVALID_SOCKET; 
return TRUE; 
} 
return FALSE; 
} 

//szServer连接的主机,可以是下列形式的字符串: 
//easeso.com:1000 
//easeso.com 
//如果wPort不为0,则szServer不应该包含端口信息 
BOOL CUDPTrackerClient::Connect(const char * szServer,WORD wPort) 
{ 
m_strError 
= ""; 
BOOL bRes 
= FALSE; 
if ( m_socket == INVALID_SOCKET ) 
{ 
//用UDP初始化套接字 
BOOL optval = TRUE;    
m_socket 
=socket(AF_INET,SOCK_DGRAM,0); 
if(m_socket == INVALID_SOCKET) 
  
return FALSE; 
//设置超时时间 
int TimeOut=10000; 
int err = setsockopt (m_socket, SOL_SOCKET,SO_RCVTIMEO,(CHAR *) &TimeOut,sizeof (TimeOut)); 
} 
if(m_dwIP == 0) 
{ 
CString strServer 
= szServer; 
CString strHost; 
if(wPort == 0) 
{ 
  
int iNext = strServer.Find(':'); 
  
if(iNext>0) 
  {    
  strHost 
= strServer.Mid(0,iNext);    
  CString strPort 
= strServer.Mid(iNext+1);    
  m_wPort 
= (WORD)atoi(strPort); 
  } 
  
else 
  strHost 
= strServer; 
} 
else 
{ 
  strHost 
= strServer; 
  m_wPort 
= wPort; 
} 
if(m_wPort == 0) 
  m_wPort 
= 80; 

//Check if address is an IP or a Domain Name 
int a = strHost[0]; 
if (a > 47 && a < 58) 
  m_dwIP 
= inet_addr(strHost); 
else 
{ 
  
struct hostent *pHost; 
  pHost 
= gethostbyname(strHost); 
  
if(pHost != NULL) 
  m_dwIP 
= *((ULONG*)pHost->h_addr); 
  
else 
  m_dwIP 
= 0; 
} 
} 
if((GetTickCount()-m_dwConnectTick)>30000) 
{ 
m_dwConnectTick 
= 0; 
m_iConnection_id 
= 0; 
} 
if(m_socket != INVALID_SOCKET && m_dwIP && m_wPort && m_iConnection_id ==0) 
{ 
DWORD dwTransaction_id 
= GetTickCount(); 
SOCKADDR_IN from; 
int fromlength=sizeof(SOCKADDR); 

char buf[RECVBUFSIZE]; 
from.sin_family
=AF_INET; 
from.sin_addr.s_addr
=m_dwIP; 
from.sin_port
=htons(m_wPort); 
CDataStream sendstream(buf,
2047); 
sendstream.clear(); 
__int64 iCID 
= 0x41727101980; 
sendstream.writeint64(CNetworkByteOrder::convert(iCID)); 
sendstream.writedword(CNetworkByteOrder::convert((
int)0)); 
sendstream.writedword(dwTransaction_id); 

int iRes = 0; 
int iTimes = 6; 
while(iTimes>0&&m_dwIP) 
{ 
  sendto(m_socket,sendstream.getbuffer(),sendstream.size(),
0,(struct sockaddr FAR *)&from,sizeof(from)); 
  iRes 
= recvfrom(m_socket,buf,RECVBUFSIZE-1,0,(struct sockaddr FAR *)&from,(int FAR *)&fromlength); 
  
if(iRes >=0) 
  
break; 
  iTimes
--; 
} 
if(iRes>=16) 
{ 
  CDataStream recvstream(buf,RECVBUFSIZE
-1); 
  DWORD dwAction 
= (DWORD)CNetworkByteOrder::convert((int)recvstream.readdword()); 
  DWORD dwTIDResp
= recvstream.readdword(); 
  
if(dwTIDResp == dwTransaction_id) 
  { 
  
if(dwAction == 0) 
  { 
  m_iConnection_id 
= recvstream.readint64();    
  
//BitComet将回复0x16字节数据,最后6字节是服务器查看到的本地IP和UDP端口 
  } 
  
else if(dwAction == 3)//得到一个错误信息包 
  { 
  buf[iRes]
=0; 
  m_strError 
= recvstream.readstring(); 
  } 
  } 
} 
} 
if(m_iConnection_id) 
bRes 
= TRUE; 
return bRes; 
} 
//提交请求 
//pInfoHash 20字节的数据缓冲区指针 
//pPeerID 20字节的数据缓冲区指针 
//ievent参数值: 
//none = 0 
//completed = 1 
//started = 2 
//stopped = 3 

DWORD CUDPTrackerClient::Announcing(BYTE
* pInfoHash,BYTE * pPeerID, 
      __int64 idownloaded,__int64 ileft,__int64 iuploaded, 
      
int ievent, 
      DWORD dwIP,WORD wPort) 
{ 
m_listPeers.clear(); 
m_dwNumPeers 
= 0; 
m_dwDonePeers 
= 0; 
m_strError 
= ""; 
DWORD dwReturnCode 
= 0; 
if(m_iConnection_id && m_socket != INVALID_SOCKET && m_dwIP & m_wPort) 
{ 
DWORD dwTransaction_id 
= GetTickCount(); 
//srand(dwTransaction_id); 
//DWORD dwKey = rand(); 
DWORD dwKey = 0x3753; 
SOCKADDR_IN from; 
int fromlength=sizeof(SOCKADDR); 
char buf[RECVBUFSIZE]; 
from.sin_family
=AF_INET; 
from.sin_addr.s_addr
=m_dwIP; 
from.sin_port
=htons(m_wPort); 
CDataStream sendstream(buf,RECVBUFSIZE
-1); 
sendstream.clear(); 
sendstream.writeint64(m_iConnection_id); 
sendstream.writedword(CNetworkByteOrder::convert((
int)1)); 
sendstream.writedword(dwTransaction_id); 
sendstream.writedata(pInfoHash,
20); 
sendstream.writedata(pPeerID,
20); 
sendstream.writeint64(CNetworkByteOrder::convert(idownloaded)); 
sendstream.writeint64(CNetworkByteOrder::convert(ileft)); 
sendstream.writeint64(CNetworkByteOrder::convert(iuploaded)); 
sendstream.writedword(CNetworkByteOrder::convert(ievent)); 
sendstream.writedword(dwIP); 
sendstream.writedword(CNetworkByteOrder::convert((
int)dwKey)); 
sendstream.writedword(CNetworkByteOrder::convert((
int)200)); 
sendstream.writedword(CNetworkByteOrder::convert(wPort)); 

int iRes = 0; 
int iTimes = 2; 
while(iTimes>0&&m_dwIP) 
{ 
  sendto(m_socket,sendstream.getbuffer(),sendstream.size(),
0,(struct sockaddr FAR *)&from,sizeof(from)); 
  iRes 
= recvfrom(m_socket,buf,RECVBUFSIZE-1,0,(struct sockaddr FAR *)&from,(int FAR *)&fromlength); 
  
if(iRes >=0) 
  
break; 
  iTimes
--; 
} 
if(iRes>=20) 
{    
  CDataStream recvstream(buf,RECVBUFSIZE
-1); 
  DWORD dwAction 
= (DWORD)CNetworkByteOrder::convert((int)recvstream.readdword()); 
  DWORD dwTIDResp
= recvstream.readdword(); 
  
if(dwTIDResp == dwTransaction_id) 
  { 
  
if(dwAction == 1) 
  { 
  m_dwInterval 
= (DWORD)CNetworkByteOrder::convert((int)recvstream.readdword()); 
  m_dwNumPeers 
= (DWORD)CNetworkByteOrder::convert((int)recvstream.readdword()); 
  m_dwDonePeers 
= (DWORD)CNetworkByteOrder::convert((int)recvstream.readdword());    
  CPeerHostInfo hi;    
  
for(int iCurPos = 20;iCurPos+6<=iRes;iCurPos+=6) 
  { 
    hi.IP
= recvstream.readdword(); 
    hi.Port 
= (WORD)CNetworkByteOrder::convert((unsigned short)recvstream.readword()); 
    m_listPeers.push_back(hi); 
  } 
  
if(m_dwNumPeers>m_listPeers.size()) 
  { 
    iRes 
= 0; 
    iTimes 
= 6; 
    
while(iTimes>0&&m_dwIP) 
    { 
    iRes 
= recvfrom(m_socket,buf,RECVBUFSIZE-1,0,(struct sockaddr FAR *)&from,(int FAR *)&fromlength); 
    
if(iRes >=0) 
    
break; 
    iTimes
--; 
    } 
    
if(iRes>=6) 
    { 
    
for(iCurPos = 0;iCurPos+6<=iRes;iCurPos+=6) 
    { 
    hi.IP
= recvstream.readdword(); 
    hi.Port 
= (DWORD)CNetworkByteOrder::convert((int)recvstream.readword()); 
    m_listPeers.push_back(hi); 
    } 
    }     
  } 
  m_dwNumPeers 
= m_listPeers.size(); 
  dwReturnCode 
= 200; 
  } 
  
else if(dwAction == 3)//得到一个错误信息包 
  { 
  buf[iRes]
=0; 
  m_strError 
= recvstream.readstring(); 
  dwReturnCode 
= 400; 
  } 
  } 
} 
} 
//每次都要求重新连接 
m_iConnection_id = 0; 
return dwReturnCode; 
} 
// DataStream.h: interface for the CDataStream class. 
// 
////////////////////////////////////////////////////////////////////// 

#if !defined(AFX_DATASTREAM_H__D90A2534_EA73_4BEA_8B7E_87E59A3D1D26__INCLUDED_) 
#define AFX_DATASTREAM_H__D90A2534_EA73_4BEA_8B7E_87E59A3D1D26__INCLUDED_ 

#if _MSC_VER > 1000 
#pragma once 
#endif // _MSC_VER > 1000 
#include 
//数据流操作函数 
class CDataStream 
{ 
public : 
CDataStream(
char * szBuf,int isize) 
{ 
m_isize 
= isize; 
buffer 
= szBuf; 
current 
= buffer; 
} 
~CDataStream() 
{ 
} 
  
void clear() 
{ 
current 
= buffer; 
current[
0]=0; 
} 
//此函数不动态增加内存,一次打印的数据长度不应该超过缓冲区的三分之一,否则可能导致失败 
bool printf(const char * format,...) 
{ 
if(current) 
{ 
  
if(current - buffer > (m_isize*2)/3) 
  
return false; 
  va_list argPtr ; 
  va_start( argPtr, format ) ; 
  
int count = vsprintf( current, format, argPtr ) ; 
  va_end( argPtr ); 
  current 
+= count ; 
  
return true; 
} 
return false; 
} 
//此函数拷贝字符串 
bool strcpy(const char * szStr) 
{ 
if(current&&szStr) 
{ 
  
int ilen = lstrlen(szStr); 
  
if((m_isize-(current - buffer)) < (ilen +2)) 
  
return false; 
  memcpy(current,szStr,ilen
+1); 
  current 
+= ilen; 
  
return true; 
} 
return false; 
} 
char * getcurrentpos() 
{ 
return current; 
} 
void move(int ilen)//当前指针向后移动ilen 
{ 
current 
+= ilen; 
} 
void reset() 
{ 
current 
= buffer; 
} 
BYTE readbyte() 
{ 
current 
++; 
return *(current-1); 
} 
void writebyte(BYTE btValue) 
{ 
*current = btValue; 
current 
++; 
} 
WORD readword() 
{ 
current 
+=2; 
return *((WORD*)(current-2)); 
} 
void writeword(WORD wValue) 
{ 
*((WORD*)current) = wValue; 
current 
+=2; 
} 
DWORD readdword() 
{ 
current 
+=4; 
return *((DWORD*)(current-4)); 
} 
void writedword(DWORD dwValue) 
{ 
*((DWORD*)current) = dwValue; 
current 
+=4; 
} 
__int64 readint64() 
{ 
current 
+=8; 
return *((__int64*)(current-8)); 
} 
void writeint64(__int64 iValue) 
{ 
*((__int64*)current) = iValue; 
current 
+=8; 
} 
BYTE 
* readdata(DWORD dwLen) 
{ 
current 
+=dwLen; 
return (BYTE*)(current-dwLen); 
} 
void writedata(BYTE * pData,DWORD dwLen) 
{ 
memcpy(current,pData,dwLen); 
current 
+=dwLen; 
} 
char * readstring() 
{ 
char * szRes = current; 
int ilen = lstrlen(current); 
current 
+=(ilen+1); 
return szRes; 
} 
int size() 
{ 
return (int)(current-buffer); 
} 
const char * getbuffer(){return buffer;} 
private : 
char* buffer; 
  
char* current; 
int m_isize; 
}; 
class CNetworkByteOrder 
{ 
public: 
static unsigned short int convert(unsigned short int iValue) 
{ 
unsigned 
short int iData; 
((BYTE
*)&iData)[0] = ((BYTE*)&iValue)[1]; 
((BYTE
*)&iData)[1] = ((BYTE*)&iValue)[0]; 
return iData; 
} 
static int convert(int iValue) 
{ 
int iData; 
((BYTE
*)&iData)[0] = ((BYTE*)&iValue)[3]; 
((BYTE
*)&iData)[1] = ((BYTE*)&iValue)[2]; 
((BYTE
*)&iData)[2] = ((BYTE*)&iValue)[1]; 
((BYTE
*)&iData)[3] = ((BYTE*)&iValue)[0]; 
return iData; 
} 
static __int64 convert(__int64 iValue) 
{ 
__int64 iData; 
((BYTE
*)&iData)[0] = ((BYTE*)&iValue)[7]; 
((BYTE
*)&iData)[1] = ((BYTE*)&iValue)[6]; 
((BYTE
*)&iData)[2] = ((BYTE*)&iValue)[5]; 
((BYTE
*)&iData)[3] = ((BYTE*)&iValue)[4]; 
((BYTE
*)&iData)[4] = ((BYTE*)&iValue)[3]; 
((BYTE
*)&iData)[5] = ((BYTE*)&iValue)[2]; 
((BYTE
*)&iData)[6] = ((BYTE*)&iValue)[1]; 
((BYTE
*)&iData)[7] = ((BYTE*)&iValue)[0]; 
return iData; 
} 

}; 
#endif // !defined(AFX_DATASTREAM_H__D90A2534_EA73_4BEA_8B7E_87E59A3D1D26__INCLUDED_)


 

2 海康视觉平台VisionMaster 上手系列:大纲及准备 海康视觉平台VisionMaster 大纲,课前准备 快速入门 工业机器视觉 机器视觉 阅读详情

相关推荐

使用Tansformer分割三维腹部多器官--UNETR实战

不会 transformer 没关系,本教程开箱即用。Tina姐总算对transformer下手了,之前觉得难,因为刚开始学序列模型的时候就没学会。然后就一直排斥学transformer。这两周没什么事,加上MONAI有现成的教程,就打算先跑通后,再学理论。然后,顺利的跑通了代码,再学了一周理论,发现它也不过如此嘛,入门还是很容易的。有同学想了解的transformer的话,可以先看完这个实战教程,如果感兴趣,后续会出一个transformer入门路线。利用纯Transformers作为编码器来学习输入量的

Tina姐的博客 1万+

BT协议集合

BT协议集合2008-02-25 18:20BitTorrent 协议规范(BT协议集合)一 BitTorrent 是一种分发文件的协议。它通过URL来识别内容,并且可以无缝的和web进行交互。它基于HTTP协议,它的优势是:如果有多个下载者并发的下载同一个文件,那么,每个下载者也同时为其它下载者上传文件,这样,文件源可以支持大量的用户进行下载,而只带来适当的负载的增长

Lixinag的专栏 1893

SQL-拼多多 面试题:连续3次为球队得分的球员名单

1.使用LAG开窗函数 筛选出 下一次和下下一次得分,并用进球时间进行排序。2.使用where筛选出值得嘉奖的球员。

Ftr1998的博客 643

BitTorrent 协议规范(BT协议集合)十二

作者:小马哥 概述: 相对于 tracker 服务器来说,BT客户端要复杂的多,Bram Cohen 花了一年 full time 的时间来完成 BT,我估计其中大部分时间是用在 BT 客户端的实现和调试上了。 由于 BT 客户端涉及的代码比较多,我不能再象分析 tracker 服务器那样,走上来就深入到细节之中去,那样的话,我写的晕晕糊糊,大家看起来也不知所云。所以第一篇文章先来谈谈客户端的功能

1037

生物信息学避坑指南:Scissor算法参数alpha和cutoff的黄金设置法则

本文深入解析了生物信息学中Scissor算法的关键参数alpha和cutoff的黄金设置法则,帮助研究者有效整合bulk RNA与单细胞数据,识别单细胞亚群。通过实战验证的调参策略,避开常见陷阱,获得可靠的生物学发现,特别适用于肿瘤异质性研究和免疫细胞分型等场景。

weixin_33734785的博客 451

openEuler 22.03 LTS SP4离线安装UKUI桌面全攻略(附依赖包下载)

本文提供openEuler 22.03 LTS SP4系统离线安装UKUI桌面环境的完整实战指南。针对无网络环境,详细解析了利用dnf工具下载依赖包、配置离线软件源、处理依赖冲突及安装后优化的全流程,并附带了关键依赖包资源,帮助运维人员高效完成图形化部署。

c7d8e9的博客 482

BitTorrent 协议规范(BT协议集合)二三

概要      上一节我们分析了BT客户端与tracker之间的通信过程。通过与 tracker 的通信,客户端获得了参与下载的其它peers 的列表。有了这些 peers 的信息,客户端就可以主动向它们发起连接,为进一步从它们那里获取所需要的文件片断做好准备。这些连接称为“主动连接”。因为连接的发起方是客户端自己。      同时,每个客户端在启动以后,都会监听某个端口,用于接受其它 peers

1265

固定效应模型-以stata为工具

固定效应模型(Fixed Effects Model)是一种面板数据分析方法,通过引入个体固定效应来控制个体间的异质性,并更准确地估计解释变量对因变量的影响。它在许多经济、社会科学和健康研究中被广泛应用。

侯小啾技术博客 2839

BitTorrent 协议规范(BT协议集合)二二

昨天重新读了BT协议和客户端代码,发现对协议本身部分比较熟悉了,但是对BT在实际运行期间各种行为的发生情景还非常模糊,有些步骤还想清楚,大家一起来讨论一下. 我们来一起描述一下BT各种消息的发送情景. 有些不是特别肯定的我没有加上,大家在这个基础上进行增加或者修改. 其中client指本机上运行的BT客户端.peer指tracker返回的远程客户端. piece指torrent文件中的20byte

1297

23、工业物流中的多智能体路径规划与碰撞处理策略

本文探讨了工业4.0背景下工业物流中的多智能体路径规划(MAPF)与碰撞处理策略。分析了自动导引车(AGV)等移动资源的应用现状,综述了主流路径规划算法如A*、D*Lite、M*等,以及集中式与分布式碰撞检测方法。重点比较了五种碰撞避免策略:路径交叉、优先级、起始时间调整、无交叉路径和速度调整,提出了基于环境条件的策略选择流程,并通过流程图展示了评估、组合、测试与优化的全过程。文章强调应根据订单不确定性、时间约束、优先级和生产组织等因素综合选择或组合策略,以提升物流效率与系统可靠性。

mac99的博客 125

【AI智能体】Codex 生成高质量电商套图实战操作详解

Codex 生成高质量电商套图实战操作详解

congge 4524

BitTorrent 协议规范(BT协议集合)三

Bittorrent udp-tracker protocol extension Contents introduction connecting Client sends packet: Server replies with packet: announcing Client sends packet: Server replies with packet: scraping Client

1029

Python散点图(Scatter Plot):高阶分析、散点图矩阵、三维散点图及综合应用

散点图作为一种直观且功能强大的数据可视化工具,在数据分析中具有广泛的应用。通过观察散点图中数据点的分布模式,我们可以轻松地判断变量之间是否存在相关性,以及相关性的类型和强度。同时,散点图也是识别数据集中异常值的有效工具,无论是通过直观观察还是结合统计方法,都能帮助我们发现数据中的异常情况。掌握散点图的绘制和分析技巧,将使我们在数据探索和决策制定中更加得心应手。

SiArch的博客 1444

BitTorrent 协议规范(BT协议集合)二四

BitTorrent是一个优秀的P2P下载软件,国内又叫它BT(变态)。 BT的主页:http://bitconjurer.org/BitTorrent/index.html BT的作者:Bram Cohen,《程序员》杂志2004第3期有对他的介绍文章 BT所用的语言:python python:一种优秀的动态语言(关于动态语言的介绍,看《程序员》杂志2004年第5期)。 python的官方网站

1541

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

BitTorrent 协议规范(BT协议集合)十八

客户端源码分析之六:客户端的主程序 作者:小马哥 前言: 自从7月份写完“客户端源码分析之五:Encoder 与 Connection 类”后,我就停止了继续对BT源码的分析。原因很多,最主要的还是懒惰吧。临到岁末,终于下定决心,无论如何,要完成这一系列的文章,对自己也算有个交待。 前面的几篇文章,都是深入到源码的某一部分细节之中,虽然很清晰,但无助于读者对整体构架的把握(其实我自己当时也比较糊涂

926

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

BitTorrent 协议规范(BT协议集合)

BitTorrent 协议规范(BT协议集合)翻译:小马哥 日期:2004-5-22 BitTorrent 是一种分发文件的协议。它通过URL来识别内容,并且可以无缝的和web进行交互。它基于HTTP协议,它的优势是:如果有多个下载者并发的下载同一个文件,那么,每个下载者也同时为其它下载者上传文件,这样,文件源可以支持大量的用户进行下载,而只带来适当的负载的增长。(译注:因为大量的负载被均衡到整个

gogl的专栏 1875

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

BitTorrent 协议规范(BT协议集合)二

这个翻译版本由孤波独立完成 原文见http://bitconjurer.org/BitTorrent/protocol.html 作者Bram Cohen 孤波享有对该翻译版本解释权修改权 非商业引用请注明译者 BitTorrent协议详解 BitTrrent(简称BT,比特洪流)是一个文件分发协议,它通过URL识别内容并且和网络无缝结合。它在HTTP平台上的优势在于,同时下在一个文件的下载者在下

1043

BitTorrent 协议规范(BT协议集合)一

BitTorrent 是一种分发文件的协议。它通过URL来识别内容,并且可以无缝的和web进行交互。它基于HTTP协议,它的优势是:如果有多个下载者并发的下载同一个文件,那么,每个下载者也同时为其它下载者上传文件,这样,文件源可以支持大量的用户进行下载,而只带来适当的负载的增长。(译注:因为大量的负载被均衡到整个系统中,所以提供源文件的机器的负载只有少量增长) 一个BT文件分布系统由下列实体组成:

1026

BitTorrent 协议规范(BT协议集合)十七

Encoder 是一种 Handler 类(关于 Handler类,请参看前面的分析文章)。它在 download.py 中被初始化。它与 Connection类一起,完成“BT对等连接”的建立,以及“BT对等协议”的分析。 为了有助于理解,我添加了一些用圆圈括起来的序号,建议你按照这个顺序去阅读。 class Connection:   ②def __init__(self, Encoder,

929

BitTorrent 协议规范(BT协议集合)九

Tracker服务器源码分析之一:总述 作者:小马哥 日期:2004-5-29   tracker服务器是BT下载中必须的角色。一个BT client 在下载开始以及下载进行的过程中,要不停的与 tracker 服务器进行通信,以报告自己的信息,并获取其它下载client的信息。这种通信是通过 HTTP 协议进行的,又被称为 tracker HTTP 协议,它的过程是这样的:   client 向

1320

BitTorrent 协议规范(BT协议集合)二十

作者:小马哥 本篇文章分析 Tracker 类,它在 track.py 文件中。 在分析之前,我们把前几篇文章的内容再回顾一下,以理清思路。 BT的源码,主要可以分为两个部分,一部分用来实现 tracker 服务器,另一部分用来实现BT的客户端。我们这个系列的文章围绕 tracker 服务器的实现来展开。 BT 客户端与 tracker 服务器之间,通过 track HTTP协议进行通信,而BT客

1057

BitTorrent 协议规范(BT协议集合)十九

客户端源码分析之七:客户端与tracker通信过程4VM 作者:小马哥 l概要 上一节我们分析了BT客户端主程序的框架:一个循环的服务器程序。在这个循环过程中,客户端要完成如下任务:l Ø与 tracker 服务器通信;汇报自己的状态,同时获取其它 peers 的信息;. Ø接受其它 peers 的连接请求;a%dv Ø主动向某些 peers 发起连接请求;8 Ø对BT对等协议的分析处理;kn Ø

1259

BitTorrent 协议规范(BT协议集合)二一

 BT客户端开始一个下载首先要处理的就是torrent文件. 而torrent文件使用bencoding编码. 所以实现bencoding编码的解析器,就是第一步工作. Bencoding is done as follows: Strings are length-prefixed base ten followed by a colon and the string. For e xample

987

BitTorrent 协议规范(BT协议集合)十

Tracker服务器源码分析之二:RawServer类 作者:小马哥 这篇文章,我们来分析 RawServer 以及一些相关的类。RawServer 类的实现代码,在 BitTorrent 子目录的RawServer.py 中 RawServer 这个类的作用是实现一个网络服务器。关于网络编程的知识,《unix网络编程:卷1》是最经典的书籍,你如果对这块不了解,建议抽时间看看这本书。RawServ

1208

BitTorrent 协议规范(BT协议集合)六

BT是如何采用激励机制来达到健壮性的 Bram Cohen bram@bitconjurer.org 2003年5月22日 翻译:小马哥 日期:2004-6-1 修改:扬帆 日期:2005-5-9 概要 BitTorrent 文件发布系统采用针锋相对(tit_for_tat)的方法来达到帕累托有效,与当前已知的协作技术相比,它具有更高的活力。本文将解释BitTorrent 的用途,以及是怎样用经济

1100

BitTorrent 协议规范(BT协议集合)十六

PiecePicker 用于实现“片断选择算法”,片断选择算法在《Incentives Build Robustness in BitTorrent》一文中有介绍,我把相关内容列出来。 BT的片断选择算法,综合下面几种策略。 l       严格的优先级   片断选择的第一个策略是:一旦请求了某个片断的子片断,那么该片断剩下的子片断优先被请求。这样,可以尽可能快的获得一个完整的片断 l      

852
上一篇: BitTorrent 协议规范(BT协议集合)三
下一篇: BitTorrent 协议规范(BT协议集合)五
Pregunta
博客等级 码龄23年 6粉丝 19原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值