众所周知QQ是主要采用UDP通信协议来通信的,在QQ登陆时,服务器会返回在线好友列表 和离线消息,譬如要服务器用UDP返回好友列表时(包括好友的QQ号码、IP还有其他信息),是不是先把好友的信息读入一个内存流然后再用winsock发回给客户端呢?如果客户端要接受的话,应该怎样实现分段接受然后把个个信息分别拆开来?(因为返回的是一个好友列表,一个好友信息有:好友的QQ号码、IP还有其他信息等。又或者不是用这种方式来实现呢?请高手指点迷津!小弟愿意听教!
(在线等待)
(在线等待)
解决方案 »
- 关于 LPCSTR 强制转换的问题,请那位大哥来帮下忙,感激不尽
- 如何关闭父窗口的最小,最大,关闭按钮
- 哪里能找到可以显示Ftp源或者Http源的图片的Activex插件?
- 如何使用SQL语句创建DataBase(Access 2000)
- 自定义的IDownloadManager下载接口的问题?
- 求助:对一个未命名的文件查找失败
- readflie堵塞,用TerminateThread结束线程,在用AfxBeginThread创建线程。线程函数没运行。
- OnMouseMove()中,当鼠标移出客户区,怎样发出一个提示(AfxMessageBox("out"))?
- 用VC写程序,感觉无从下手怎么办???苦恼呀!!!:(
- BHO如何处理showModalDialog
- 推荐几本适合VC初学者阅读的书?
- 急(高分):如何在vc程序打开之前,读入notepad中的字符串,而在关闭之后,往notepad中写入字符串
[email protected]
谢谢
thanks!!
[email protected]
多谢!多谢!希望是真的!
另外,我认为你首先应该用帧听工具将qq的封包格式分析一下,有了一个大致的了解以后再分析
万分感谢!
[email protected]
下面的只是一部分.
// data.h: interface for the CData class.
//
//////////////////////////////////////////////////////////////////////#if !defined(AFX_DATA_H__F849DA10_B160_11CF_BC5B_5254AB4B2098__INCLUDED_)
#define AFX_DATA_H__F849DA10_B160_11CF_BC5B_5254AB4B2098__INCLUDED_#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000#define Max_Data_Length 1024class CData
{
public:
CData();
virtual ~CData();
//methods and operations
public:
virtual void Build(); //将数据缓冲区中的数据解码到成员中
virtual BOOL Load(); //填充数据缓冲区
//data members
public:
BYTE type ; //消息类型
BYTE WndIndex; //处理该消息的窗口句柄索引
DWORD flag ; //消息标记 UINT dstPort ; //目的IP地址
UINT dstIP ; //目的端口号
char buffer[Max_Data_Length] ; //数据缓冲区
WORD buf_len ; //数据缓冲区中数据长度
WORD buf_offset; //数据缓冲区中特殊数据的偏移
private:protected:
};inline void CopyData(CData *dst,CData *src)
{
for ( int i = 0 ;i < src->buf_len ; i ++ )
dst->buffer[i] = src->buffer[i] ;
dst->type = src->type ;
dst->dstIP = src->dstIP ;
dst->dstPort = src->dstPort ;
dst->WndIndex = src->WndIndex ;
dst->buf_len = src->buf_len ;
dst->buf_offset = src->buf_offset ;
}#endif // !defined(AFX_DATA_H__F849DA10_B160_11CF_BC5B_5254AB4B2098__INCLUDED_)
///
// data.cpp: implementation of the CData class.
//
//////////////////////////////////////////////////////////////////////
#include "data.h"#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////CData::CData()
{
type = 0;
WndIndex = 0 ;
dstPort = 0;
dstIP = 0
buf_len = 0 ;
buf_offset = 0 ;
flag = 0 ;
memset(buffer,0,Max_Data_Length);
}CData::~CData()
{}void CData::Build()
{
char *cp = buffer ; //开头是固定数据
*(BYTE *)cp = type ; //消息类型
cp += sizeof(BYTE) ; *(BYTE *)cp = WndIndex ; //窗口句柄索引
cp += sizeof(BYTE); *(DWORD *)cp = flag ; //消息标记
cp += sizeof(DWORD) ; //以下是附加数据的开始地址
buf_len = cp - buffer ;
buf_offset = cp - buffer ;//用户数据的偏移量
}BOOL CData::Load()
{
char *cp = buffer ; type = *(BYTE *)cp ; // 消息类型
cp += sizeof(BYTE) ; WndIndex = *cp ; //窗口句柄索引
if( WndIndex < 0 && WndIndex >= MaxRecvWndCount )
return FALSE ;
cp += sizeof(WndIndex); flag = *(DWORD *)cp;
cp += sizeof(DWORD); buf_offset = cp - buffer ;//用户数据的偏移量 return (buf_offset <= buf_len );
}
////////////////////////////////////////////////////////////Talker的基本信息
#define Max_String_len 32 class CTalkerBaseInfo
{
public:
CTalkerBaseInfo();
virtual ~CTalkerBaseInfo();
public:
char pet_name[ Max_String_len ] ;
char real_name[ Max_String_len ] ;
char pass_word[ Max_String_len ] ;
char dept[ Max_String_len ] ;
char occupation[ Max_String_len ];
char email[ Max_String_len*2 ] ;
char homepage[ Max_String_len*2 ];
char desc[ Max_String_len*2 ] ;
BYTE sex ;
BYTE age ;
WORD ID ; //唯一标识符
BYTE character;//1=可以被加为好友,2=需要身份验证,4=拒绝被加为好友;
BYTE pic_idx; //头像编号
};
class CTalker : public CTalkerBaseInfo
{
public:
CTalker();
virtual ~CTalker();
public:
BYTE status ; //状态
UINT ip ; //当前的IP地址
UINT port ; //当前的PORT号
DWORD dwTickCount ;
};
//
class CTalker : public CTalkerBaseInfo
{
public:
CTalker();
virtual ~CTalker();
public:
BYTE status ; //状态
UINT ip ; //当前的IP地址
UINT port ; //当前的PORT号
DWORD dwTickCount ;
};
//
//////////////////////////////////////////////////////////////////////
#include "Talker.h"#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif//////////////////////////////////////////////////////////////////////
// CTalkerBaseInfo Class
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////CTalkerBaseInfo::CTalkerBaseInfo()
{
memset(this, 0, sizeof( *this ) );
}CTalkerBaseInfo::~CTalkerBaseInfo()
{}//////////////////////////////////////////////////////////////////////
// CTalker Class
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////CTalker::CTalker()
{
status = 0 ; //状态
ip = 0 ; //当前的IP地址
port = 0 ; //当前的PORT号
dwTickCount = 0 ;
}CTalker::~CTalker()
{}
//////////////////////////////////////////////
class CMsgTalkerDetail : public CData
{
public:
virtual void Build();
virtual BOOL Load();
public:
CMsgTalkerDetail();
virtual ~CMsgTalkerDetail();
public:
DWORD options;
CTalker talker ;
};//////////////////////////////////////////////////////////////////////
// CMsgTalkerDetail Class
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////CMsgTalkerDetail::CMsgTalkerDetail()
{
options = 0 ;
memset(&talker, 0, sizeof(CTalker));
}CMsgTalkerDetail::~CMsgTalkerDetail()
{}
{
CData::Build() ;
char *cp = (char *)(buffer + buf_offset ); BYTE iLen = 0 ; *(DWORD *)cp = options ;
cp += sizeof( DWORD ); //用户信息用TLV编码格式发送
if ( ( iLen = strlen(talker.pet_name) ) > 0 )
{
*(BYTE *)cp = PETNAME ; //type
cp += sizeof( BYTE );
*(BYTE *)cp = iLen ; //length
cp += sizeof( BYTE );
memcpy(cp,talker.pet_name,iLen); //value
cp += iLen ;
}
if ( ( iLen = strlen(talker.real_name ) ) > 0 )
{
*(BYTE *)cp = REALNAME ; //type
cp += sizeof( BYTE );
*(BYTE *)cp = iLen ; //length
cp += sizeof( BYTE );
memcpy(cp,talker.real_name,iLen); //value
cp += iLen ;
}
if ( ( iLen = strlen(talker.pass_word ) ) > 0 )
{
*(BYTE *)cp = PASSWORD ; //type
cp += sizeof( BYTE );
*(BYTE *)cp = iLen ; //length
cp += sizeof( BYTE );
memcpy(cp,talker.pass_word,iLen); //value
cp += iLen ;
}
if ( ( iLen = strlen(talker.dept ) ) > 0 )
{
*(BYTE *)cp = DEPT ; //type
cp += sizeof( BYTE );
*(BYTE *)cp = iLen ; //length
cp += sizeof( BYTE );
memcpy(cp,talker.dept,iLen); //value
cp += iLen ;
}
if ( ( iLen = strlen(talker.occupation ) ) > 0 )
{
*(BYTE *)cp = OCCUPATION ; //type
cp += sizeof( BYTE );
*(BYTE *)cp = iLen ; //length
cp += sizeof( BYTE );
memcpy(cp,talker.occupation,iLen); //value
cp += iLen ;
}
if ( ( iLen = strlen(talker.email ) ) > 0 )
{
*(BYTE *)cp = EMAIL ; //type
cp += sizeof( BYTE );
*(BYTE *)cp = iLen ; //length
cp += sizeof( BYTE );
memcpy(cp,talker.email,iLen); //value
cp += iLen ;
}
if ( ( iLen = strlen(talker.homepage ) ) > 0 )
{
*(BYTE *)cp = HOMEPAGE ; //type
cp += sizeof( BYTE );
*(BYTE *)cp = iLen ; //length
cp += sizeof( BYTE );
memcpy(cp,talker.homepage,iLen); //value
cp += iLen ;
}
if ( ( iLen = strlen(talker.desc ) ) > 0 )
{
*(BYTE *)cp = DESCRIPT ; //type
cp += sizeof( BYTE );
*(BYTE *)cp = iLen ; //length
cp += sizeof( BYTE );
memcpy(cp,talker.desc,iLen); //value
cp += iLen ;
} *(BYTE *)cp = SEX ; //type = SEX
cp += sizeof(BYTE); //没有长度,只有值
*(BYTE *)cp = talker.sex ; //value = talker.sex
cp += sizeof(BYTE); //2字节 *(BYTE *)cp = AGE ; //type = AGE
cp += sizeof(BYTE); //没有长度,只有值
*(BYTE *)cp = talker.age ; //value = talker.sex
cp += sizeof(BYTE); //2字节 *(BYTE *)cp = USERID ; //type = USERID
cp += sizeof(BYTE); //没有长度,只有值
*(WORD *)cp = talker.ID ; //value = talker.ID
cp += sizeof(WORD); //3字节 *(BYTE *)cp = STATUS ; //type = STATUS
cp += sizeof(BYTE); //没有长度,只有值
*(BYTE *)cp = talker.status; //value = talker.status
cp += sizeof(BYTE); //2字节 *(BYTE *)cp = PIC_IDX ; //type = PIC_IDX
cp += sizeof(BYTE); //没有长度,只有值
*(BYTE *)cp = talker.pic_idx; //value = talker.status
cp += sizeof(BYTE); //2字节 *(BYTE *)cp = CHARACTER ; //type = CHARACTER
cp += sizeof(BYTE); //没有长度,只有值
*(BYTE *)cp = talker.character; //value = talker.character
cp += sizeof(BYTE); //2字节 *(BYTE *)cp = IPADDR ; //type = IPADDR
cp += sizeof(BYTE); //没有长度,只有值
*(UINT *)cp = talker.ip; //value = talker.ip
cp += sizeof(UINT); //5字节 *(BYTE *)cp = PORT ; //type = PORT
cp += sizeof(BYTE); //没有长度,只有值
*(UINT *)cp = talker.port; //value = talker.port
cp += sizeof(UINT); //5字节 *(BYTE *)cp = TYPE_END ;
cp += sizeof(BYTE); //1字节 buf_len = ( cp - buffer );
buf_offset = ( cp - buffer );
}
多谢!!!
[email protected]
[email protected]谢谢!
[email protected]
呵呵,这么多份,你给得过来吗???:)
可以将你的那个用VC写成的代码给我吗?我不想再整理你的代码!
[email protected]
thank you!
[email protected]
谢谢!
[email protected]
Thank you
[email protected]
[email protected]
谢谢。
[email protected]
谢谢!
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
谢谢
我也想要一份:[email protected]
[email protected]
thank you very much.
多谢!多谢!希望是真的!
[email protected]
[email protected]
[email protected]
[email protected]
谢谢
谢谢
thank u.
谢谢
多谢了!
[email protected]
好东西大家分享[email protected]谢了
[email protected]
非常感谢!!
我也要
3X
[email protected]