我想了解一下icq ,oicq的开发思想(我了解一点不知对否??)

stone_w8 2000-09-11 10:41:00
用socket,然后server在作数据库操作,(delete,add,update) 在client端创建好友信息文件,我已有公共聊天的源程序,但我不知如何一对一的聊天,
...全文
318 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
icedian 2000-09-25
  • 打赏
  • 举报
回复
关注
ppc207 2000-09-25
  • 打赏
  • 举报
回复
请大家来共同研究:

ICQ通讯协议
仿制ICQ已经有多个仿制品出来了,尽管功能上不是完全的,但是至少实现了部分功能,
详细的技术细节可以到ICQ-DEV新闻组里去看。
需要做什么这篇文章最大的不足是没有分析ICQ协议版本3和版本4,早期的ICQ测试版本好象只用到了版本3,而ICQ98和最新的版本好象用到了版本3和版本4。这篇文章只分析了版本2,在ICQ98之前的版本里用到。这里的版本指的是WINDOWS平台下的ICQ版本。
那么,版本2和版本3、版本4之间到底有没有区别呢?我能告诉你的是,在版本3和版本4中,一些唯一性代码被附加到了包后面。我猜想是为了防止包欺骗的手段,但是不敢肯定。我不知道那些代码是如何产生的,如果有人知道,请告诉我。另一个大的改变是包的格式。包的基本结构还是没有改变,幸运的是。尽管用这篇文章不能制作出一个ICQ的仿制品,但是ICQ服务器还在支持版本2,不过也许不久之后就不能用了,就像版本1现在已经完全不能用了。另外,有些字段被标上了“UNKNOWN”,被填充上了一些典型的值。许多包类型被本文忽略了,如果Mirabilis公司使用了所有10多种包格式,那真是他们的错误:-)另外,我对点对点通信还没大弄清除。
另外,ICQ的一些特性也没有提到,包括文件传输,聊天。
介绍
------------
在线的同一个用户交流是直接使用TCP协议完成的,而其他操作都是通过UDP包,发送
到服务器上去完成的。所有的UDP包必须被接受者识别。如果接受者不能识别,10秒
后将重传包。如果6次都没成功,则一个 B_MESSAGE_ACK 被发送,整个过程被重复两次,
如果还是没有响应,则ICQ客户端认为用户已经离线了。
在所有通信之前,客户端必须登陆到服务器上去以完成注册。在登陆的过程中,客户
端将自己的信息发送给服务器,包括IP地址,TCP端口,用户口令,用户的联络表,
之后,客户端认为在线了。在线后,客户端还将周期性地发送“活动”消息给服务器,
“活动”消息表示客户仍在访问服务器,以及让服务器知道客户还在线。缺省地,客户
将使用端口4000,UDP协议连接服务器。
发送离线消息、获取用户信息、在ICQ全球目录里搜索用户、修改口令等操作是通过
发送UDP包给服务器完成的,这些包都遵循一个模式,首先是发送者的UIN,然后是
可选的操作参数。
当用户发送一条信息,或者URL地址等给另一个当前在线的用户时,ICQ客户必须
创建一个直接的TCP连接,然后发送消息,消息包的格式跟UDP包大致相似。当包成功
发送后,TCP连接并不断开,而是保持连接以备之后继续发送消息。当通信的双方有
一方从服务器上离线后,连接被终止。
请注意在这篇文章中,如非特别指出,所有数字都是16进制的。如果一个数多于一个
字节,则前面存的是不重要的字节,后面是重要的字节(PC/INTEL体系中的习惯)。
所有文本串前用一个两字节的LENGTH字段来表示串的长度。所有串同时以空值NULL
结束。比如,值00。当读取包的时候,可以用多种方法来知道包的长度,但是在发送
包的时候,这两者都将有。所有串都用MS WINDOWS文本编码,比如一行以回车换行结
束。
服务器和客户间的通信:UDP协议
=================================================
客户发送给服务器的UDP包有如下格式:
长度 内容(如果有) 名字 描述
------- ----------- ------- ---------------
2 bytes 02 00 VERSION 标识为一个ICQ包
2 bytes xx xx COMMAND 服务器能提供的服务的代码
2 bytes xx xx SEQ_NUM 序列号
4 bytes xx xx xx xx UIN 发送者的UIN
变量 PARAMETERS 0 或者更多的参数(依赖COMMAND决定)
服务器发回给客户的UDP包有如下格式:
长度 内容 名字 描述
------ ------------------ ---- -----------
2 bytes 02 00 VERSION 标识为一个ICQ包
2 bytes xx xx COMMAND 服务器能提供的服务的代码
2 bytes xx xx SEQ_NUM 序列号
variable PARAMETERS 0 或者更多参数 (决定于COMMAND)

VERSION 字段在所有的ICQ包中都存在,标识了包是一个ICQ包。SEQ_NUM 字段包含了包
的序列号。所有的包都必须有一个序列号,而且序列号是唯一的(除非是重发包)。
序列号用来在包丢失的情况下防止混乱或重复。通常,SEQ_NUM字段为前一个包的SEQ_NUM
加一,注意服务器和客户分别采用不同的编号。所以,一个SEQ_NUM为3从服务器到客户的
包不同于SEQ_NUM为3的从客户到服务器的包。另外,服务器从00 00开始记数,而客户端
从01 00开始记数。
下面的命令可以发给服务器:
代码 名字 描述
----- --------------- -----------
0A 00 ACK 确认信息
0E 01 SEND_MESSAGE 通过服务器发送消息 (给离线用户)
E8 03 LOGIN 登陆到服务器
06 04 CONTACT_LIST 将CONTACT LIST告诉服务器
1A 04 SEARCH_UIN 使用UIN搜索用户
24 04 SEARCH_USER 使用NAME或者E-MAIL搜索用户
2E 04 KEEP_ALIVE 通知服务器当前状态还处于活动态
38 04 SEND_TEXT_CODE 以TEXT方式发送特殊的消息给服务器
4C 04 LOGIN_1 在登陆期间发送
60 04 INFO_REQ 请求一个用户的基本信息
6A 04 EXT_INFO_REQ 请求一个用户的扩展信息
9C 04 CHANGE_PASSWORD 修改用户口令
D8 04 STATUS_CHANGE 通知服务器用户离线 (比如Away)
28 05 LOGIN_2 在登陆期间发送
本问尚未详细解释的命令:
0A 05 UPDATE_INFO 更新基本信息
B0 04 UPDATE_EXT_INFO 更新扩展信息
3C 05 ADD_TO_LIST 添加用户到CONTACT LIST
56 04 REQ_ADD_TO_LIST 请求添加到CONTACT LIST的认证
BA 04 QUERY_SERVERS 查询其他服务器的地址
C4 04 QUERY_ADDONS 查询全球化的ADD-ONS
EC 04 NEW_USER_1 请求新增用户的许可
FC 03 NEW_USER_REG 注册一个新用户
A6 04 NEW_USER_INFO 发送新用户的基本信息
42 04 CMD_X1 *Unknown
56 04 MSG_TO_NEW_USER 发送消息给不在CONTACT LIST中的用户
(通常也用来发送认证请求给一个尚不在CONTACT LIST中的用户)
下面命令是服务器发送给客户的,或者是一些通知事件:
代码 名 描述
----- --------------- -----------
0A 00 ACK 确认信息
5A 00 LOGIN_REPLY 登陆回复
6E 00 USER_ONLINE CONTACT LIST里的用户在线了,或者改变状态了
78 00 USER_OFFLINE CONTACT LIST里的用户离线了
8C 00 USER_FOUND 搜索结果记录集
DC 00 RECEIVE_MESSAGE 发送离线消息成功了
A0 00 END_OF_SEARCH 没有更多的 USER_FOUND消息了
18 01 INFO_REPLY 返回一个用户的基本信息
22 01 EXT_INFO_REPLY 返回一个用户的扩展信息
A4 01 STATUS_UPDATE CONTACT LIST里的用户改变了状态(比如Away)
本文没有详细描述的命令:
1C 02 REPLY_X1 *Unknown (登陆时返回的)
E6 00 REPLY_X2 *Unknown (确认UIN?)
E0 01 UPDATE_REPLY 基本信息修改确认
C8 00 UPDATE_EXT_REPLY 扩展信息修改确认
46 00 NEW_USER_UIN 创建新用户或新UIN确认
B4 00 NEW_USER_REPLY 确认新用户的基本信息
82 00 QUERY_REPLY QUERY_SEVERS 或 QUERY_ADDONS的响应信息
C2 01 SYSTEM_MESSAGE 系统信息
下面将详细描述每一条命令。

从客户端发送的消息
===========================

ACK (0A 00) 确认
---
参数: 无
注意!不同其他的命令,ACK命令里,SEQ_NUM字段含的是客户要确认的从服务器发来
的包的序号。另外,一个ACK不会再被确认!
SEND_MESSAGE (0E 01) 通过服务器发送消息(给离线用户)
------------
参数:
长度 内容 名 描述
------- ------------------ ---- -----------
4 bytes xx xx xx xx RECEIVER_UIN 发送者的UIN
2 bytes (see below) MESSAGE_TYPE 要发送的消息类型
2 bytes xx xx LENGTH 消息长度(包含NULL)
variable MESSAGE 要发送的消息,以NULL (00)结束。
MESSAGE_TYPE 可以是如下类型:
01 00 - 正常消息
04 00 - 是一个URL,用代码FE分成两部分,前面部分是URL的描述,后面是实际的URL。

LOGIN (E8 03) 登陆到服务器
-----
参数:
长度 内容 字段名 描述
------ ------------------ ---- -----------
4 bytes xx xx xx xx PORT 用于接收消息的TCP端口
2 bytes xx xx LENGTH PASSWORD的长度(包含NULL)
variable PASSWORD 用户口令 + NULL (最多8个字符)
4 bytes 78 00 00 00 X1 *Unknown
4 bytes xx xx xx xx USER_IP 用户的IP地址
1 byte 04 X2 *Unknown
4 bytes xx xx xx xx STATUS 在线状态 (通常为00 00 00 00)
4 bytes 02 00 00 00 X3 *Unknown
2 bytes xx xx LOGIN_SEQ_NUM 登陆的序列号
4 bytes 00 00 00 00 X4 *Unknown
4 bytes 08 00 78 00 X5 *Unknown

CONTACT_LIST (06 04) 通知服务器自己的CONTACT LIST
------------
参数:
长度 内容 字段名 描述
------ ------------------ ---- -----------
2 bytes xx xx NUM_CONTACTS 接下来有多少个联系人
{4 bytes xx xx xx xx UIN CONTACT LIST中的联系人 }
最后一个字段被重复 NUM_CONTACTS 次。
服务器只发送在CONTACT LIST中的用户的在线/离线状态消息。
SEARCH_UIN (1A 04) 用 UIN 搜索用户
----------
参数:
长度 内容 字段名 描述
------ ------------------ ---- -----------
2 bytes xx xx SEARCH_SEQ_NUM 搜索的序列号
4 bytes xx xx xx xx SEARCHED_UIN 要搜索的UIN号
SEARCH_SEQ_NUM 是一个唯一的号码,服务器响应消息中将包含这个序列号。

SEARCH_USER (24 04) 用 name 或 e-mail 搜索
-----------
参数:
长度 内容 字段名 描述
------ ------------------ ---- -----------
2 bytes xx xx SEARCH_SEQ_NUM 搜索的序列号
2 bytes xx xx LENGTH NICK_NAME的长度,包括NULL
variable NICK_NAME 以NULL结束的NICKNAME
2 bytes xx xx LENGTH FIRST_NAME的长度,包括NULL
variable FIRST_NAME 以NULL结束的FIRSTNAME
2 bytes xx xx LENGTH LAST_NAME 的长度,包括NULL
variable LAST_NAME 以NULL结束的last name
2 bytes xx xx LENGTH E_MAIL 的长度,包括NULL
variable E_MAIL 以NULL结束的E-mail
注意,搜索字段(NICK_NAME, FIRST_NAME, LAST_NAME, E_MAIL)可能为空,但是不能都为空,
至少必须有一个字段包含数据。
KEEP_ALIVE (2E 04) 发送活动消息
----------
参数: 没有
周期性地发送 (经常是 2 分钟发一次)

SEND_TEXT_CODE (38 04) 以文本方式发送特殊信息
--------------
参数:
长度 内容 字段名 描述
------ ------------------ ---- -----------
2 bytes xx xx LENGTH TEXT_CODE的长度,包括 NULL
variable TEXT_CODE 以NULL结束的Message
2 bytes xx xx X1 *Unknown (code, 通常为 04 00 或 05 00)
TEXT_CODE 可以包含如下实例:
"B_USER_DISCONNECTED" (这时 X1为05 00)用户已经断开。
"B_MESSAGE_ACK" (这时 X1 为 05 00)客户端连接服务器有问题,要求服务器立即回应。

LOGIN_1 (4C 04) 在登陆期间发送
-------
参数: 无
登陆期间发送的,目的不明。

INFO_REQ (60 04) 请求一个用户的基本信息
--------
参数:
长度 内容 字段名 描述
------ ------------------ ---- -----------
2 bytes xx xx INFO_SEQ_NUM 信息序列号
4 bytes xx xx xx xx QUERY_UIN 要请求的信息的用户的UIN
服务器将返回一个 INFO_REPLY, 带着相同的 INFO_SEQ_NUM.

EXT_INFO_REQ (6A 04) 请求一个用户的扩展信息
------------
参数:
长度 内容 字段名 描述
------ ------------------ ---- -----------
2 bytes xx xx INFO_SEQ_NUM 信息序列号
4 bytes xx xx xx xx QUERY_UIN 要请求的信息的用户的UIN
服务器返回一个 EXT_INFO_REPLY, 带着同样的 INFO_SEQ_NUM.

CHANGE_PASSWORD (9C 04) 修改用户口令
---------------
参数:
长度 内容 字段名 描述
------ ------------------ ---- -----------
2 bytes xx xx PASSWORD_SEQ_NUM 口令修改序列号
2 bytes xx xx LENGTH NEW_PASSWORD 的长度,包括NULL
variable NEW_PASSWORD 新口令, NULL 结束 (最多 8 字符)

STATUS_CHANGE (D8 04) 用户已经改变了状态(比如 Away)
-------------
参数:
长度 内容 字段名 描述
------ ------------------ ---- -----------
4 bytes (see below) STATUS 用户在线状态 (比如Away)
STATUS 可以有如下值:
00 00 00 00 = Online/connected
01 00 00 00 = Away
11 00 00 00 = Do Not Disturb (DND)
00 01 00 00 = Invisible

LOGIN_2 (28 05) 登陆期间发送的
-------
参数:
长度 内容 字段名 描述
------ ------------------ ---- -----------
1 byte 00 X1 *Unknown

从服务器发回的信息
===========================

ACK (0A 00) 确认
---
参数: 无
注意!ACK所带的SEQ_NUM不同于其他的命令,他是客户端发来的请求包中带的那个号。
ACK命令不会再被确认。

LOGIN_REPLY (5A 00) 登陆响应
-----------
参数:
长度 内容 字段名 描述
------ ------------------ ---- -----------
4 bytes xx xx xx xx USER_UIN 用户的UIN
4 bytes xx xx xx xx USER_IP 用户的IP地址
2 bytes xx xx LOGIN_SEQ_NUM 登陆序列号
4 bytes 01 00 01 00 X1 *Unknown
4 bytes xx 00 16 00 X2 *Unknown (xx=19 or 18)
4 bytes 8C 00 00 00 X3 *Unknown
4 bytes 78 00 05 00 X4 *Unknown
6 bytes 0A 00 05 00 01 00 X5 *Unknown
在登陆请求后被发回,注意LOGIN_SEQ_NUM 跟LOGIN请求中的SEQ_NUM相同.

USER_ONLINE (6E 00) CONTACT LIST中的用户已经上线,或者改变了状态
-----------
参数:
长度 内容 字段名 描述
------ ------------------ ---- -----------
4 bytes xx xx xx xx REMOTE_UIN 登陆用户的UIN
4 bytes xx xx xx xx REMOTE_IP 用户的IP地址
4 bytes xx xx xx xx REMOTE_PORT 用户的端口
4 bytes xx xx xx xx REMOTE_REAL_IP 用户的实际IP地址
1 byte 04 X1 *Unknown
4 bytes xx xx xx xx STATUS 用户的新状态
4 bytes 02 00 00 00 X2 *Unkown
REMOTE_IP 是远程用户的外部(outer)IP地址,REMOTE_REAL_IP 是远程用户的内部(inner)
IP地址,第二个是在远程用户处于防火墙后时才有用的。REMOTE_PORT是可以创建直接连接的
远程用户的端口号。

USER_OFFLINE (78 00) CONTACT LIST中的用户离线了
------------
参数:
长度 内容 字段名 描述
------ ------------------ ---- -----------
4 bytes xx xx xx xx REMOTE_UIN 离线用户的UIN

USER_FOUND (8C 00) 搜索结果记录集
----------
参数:
长度 内容 字段名 描述
------ ------------------ ---- --- --------
2 bytes xx xx SEARCH_SEQ_NUM 搜索序列号
4 bytes xx xx xx xx FOUND_UIN 搜索用户的UIN
2 bytes xx xx LENGTH NICK_NAME 的长度,包括 NULL
variable NICK_NAME 以NULL结束的 nick name
2 bytes xx xx LENGTH FIRST_NAME 的长度,包括 NULL
variable FIRST_NAME 以NULL结束的 first name
2 bytes xx xx LENGTH LAST_NAME 的长度,包括 NULL
variable LAST_NAME 以NULL结束的 last name
2 bytes xx xx LENGTH E_MAIL 的长度,包括 NULL
variable E_MAIL 以NULL结束的 e-mail
1 byte xx AUTHORIZE 用户的认证状态
搜索结果中的每一条记录,都将返回一条USER_FOUND响应,当所有的USER_FOUND命令都
发送完毕,一条END_OF_SEARCH将被发送。如果没有搜索结果,命令END_OF_SEARCH将
直接被发送。 AUTHORIZE 决定了用户是否允许其他人把他加入CONTACT LIST中,通常有
两个值:
00 = 需要认证
01 = 不需要认证

RECEIVE_MESSAGE (DC 00) 离线消息发送完成
---------------
参数:
长度 内容 字段名 描述
------ ------------------ ---- -----------
4 bytes xx xx xx xx REMOTE_UIN 接受者的UIN
2 bytes xx xx YEAR 发送的年
1 byte xx MONTH 发送的月
1 byte xx DAY 发送的日期
1 byte xx HOUR 小时,GMT格式
1 byte xx MINUTE 分钟
2 bytes xx xx TYPE 消息类型,比如URL
2 bytes xx xx LENGTH 消息长度,包括NULL
variable MESSAGE 已发送的消息,以NULL结束
注意HOUR是本地时间减1(除非GMT无关?)消息类型可以是:
01 00 = 正常消息
04 00 = URL
0C 00 = 'You were added' 消息. (MESSAGE 包括: FE name> FE FE FE 。authorize
是 '1' (31)如果用户允许任意添加,否则为 '0' (30)。)

END_OF_SEARCH (A0 00) 没有USER_FOUND 可发送了
-------------
参数:
长度 内容 字段名 描述
------ ------------------ ---- -----------
2 bytes xx xx SEARCH_SEQ_NUM 搜索序列号
1 byte xx MORE_FOUND 是否有更多用户找到,但是不显示
如果 MORE_FOUND 为 00,则刚才的 USER_FOUND 包含了所有找到的用户,如果为 01,则
服务器找到了更多的用户,但是不显示了,缺省上限为40,如果一个搜索多于40,则
前40个被发送。

INFO_REPLY (18 01) 返回用户基本信息
----------
参数:
长度 内容 字段名 描述
------ ------------------ ---- -----------
2 bytes xx xx INFO_SEQ_NUM 信息序列号
4 bytes xx xx xx xx REMOTE_UIN 远程用户的UIN
2 bytes xx xx LENGTH NICK_NAME的长度, includingNULL
variable NICK_NAME 远程用户的 nick name
2 bytes xx xx LENGTH FIRST_NAME的长度, includingNULL
variable FIRST_NAME 远程用户的 first name
2 bytes xx xx LENGTH LAST_NAME的长度 includingNULL
variable LAST_NAME 远程用户的 last name
2 bytes xx xx LENGTH E_MAIL的长度 including NULL
variable E_MAIL 远程用户的 e-mail
1 byte xx AUTHORIZE 远程用户的认证状态
参数跟 USER_FOUND (8C 00)一样的。
EXT_INFO_REPLY (22 01) 返回用户扩展信息
--------------
参数:
长度 内容 字段名 描述
------ ------------------ ---- -----------
2 bytes xx xx INFO_SEQ_NUM 信息序列号
4 bytes xx xx xx xx REMOTE_UIN 远程用户的 UIN
2 bytes xx xx LENGTH Lenght of CITY including NULL
variable CITY 远程用户的 city
2 bytes xx xx COUNTRY_CODE The remote user's country code
1 byte xx COUNTRY_STATUS Indicates if COUNTRY_CODE is entered or not
2 bytes xx xx LENGTH Lenght of STATE including NULL
variable STATE 远程用户的 state (USA only)
2 bytes xx xx AGE 远程用户的 age
1 byte xx SEX 远程用户的 sex
2 bytes xx xx LENGTH Lenght of PHONE including NULL
variable PHONE 远程用户的 city
2 bytes xx xx LENGTH Lenght of HOME_PAGE includingNULL
variable HOME_PAGE 远程用户的s city
2 bytes xx xx LENGTH Lenght of ABOUT including NULL
variable ABOUT 远程用户的 city
COUNTRY_CODE 所使用的代码是国际电话号码的前缀,比如01 00 (1) 代表 USA,
2C 00 (44) 代表 UK, 2E 00 (46) 代表 Sweden, 等等。.
COUNTRY_STATUS 通常为 FE, 除非远程用户没有输入国家信息,这时为 FF FF, 同时
COUNTRY_STATUS 将为 9C。如果用户没有输入年龄,则 AGE 将为 FF FF, SEX 有三种可能的
值:
00 = 没提供
01 = 女
02 = 男
ABOUT 是一个可选的字段。

STATUS_UPDATE (A4 01) CONTACT LIST里的用户改变了状态
-------------
参数:
长度 内容 字段名 描述
------ ------------------ ---- -----------
4 bytes xx xx xx xx REMOTE_UIN 改变了状态的用户的UIN
4 bytes xx xx xx xx STATUS 新状态
参数跟 STATUS_CHANGE (D8 04)一样。

客户端间的TCP通信,点对点通信
===============================================================
当一个用户希望发送一条消息,比如URL给另一个用户,(称为远程用户,同本地用户相
对应),本地用户首先检查是否已经有TCP连接连到那个用户。如果有,则直接使用这个
连接,如果没有,则先获取该用户的信息,包括IP地址,端口等,这些信息在远程用户
登陆时,服务器将发送给本地用户。然后建立一个连接,通常,端口号在1200到1300间,
(十进制)。当新连接建立起来后,一条CHANNEL_INIT命令将发送。之后,每发送一条
消息,将发送一条CHANNEL_MESSAGE命令。所有消息必须被对方确认,使用CHANNEL_ACK,
另外,所有消息将被接收者发回一条消息作为回应--通常为一条空消息,除非用户粘贴
了Away/DND消息,这个时候他们被作为回应发送。
TCP通信跟UDP通信类似,所有的通信都是通过分离的包来完成。每个包都必须包含包的
长度信息,作为前两个字节。所有的消息将UIN作为接下来的一个字段。
CHANNEL_INIT 初始化一个通信
------------
参数:
长度 内容 字段名 描述
------ ------------------ ---- -----------
2 bytes 1A 00 LENGTH 包的长度
1 byte FF INIT_IDENT 标识这个包是一个初始包
4 bytes 02 00 00 00 X1 *Unknown
4 bytes 00 00 00 00 X2 *Unknown
4 bytes xx xx xx xx MY_UIN 本地用户的UIN
4 bytes xx xx xx xx MY_IP 本地用户的IP
4 bytes xx xx xx xx MY_IP_REAL 本地用户的实际IP
1 byte 04 X3 *Unknown
4 bytes xx xx xx xx MY_PORT 本地用户用来接收消息的端口
注意用来发送的端口跟接受端口不同。
CHANNEL_MESSAGE 发送消息给在线用户
------------
参数:
长度 内容 字段名 描述
------ ------------------ ---- -----------
2 bytes xx xx LENGTH 包的长度
4 bytes xx xx xx xx UIN 本地用户的UIN
2 bytes 02 00 VERSION 标识包为一个ICQ包
2 bytes EE 07 MSG_COMMAND 消息的类型
2 bytes 00 00 X1 *Unknown
4 bytes xx xx xx xx UIN_2 本地用户的UIN
2 bytes xx xx TYPE 消息的类型
2 bytes xx xx LENGTH 消息长度,包括NULL
variable MESSAGE 消息,以NULL结束
4 bytes xx xx xx xx MY_IP_REAL 本地用户实际IP地址
4 bytes xx xx xx xx MY_IP 本地用户IP地址
4 bytes xx xx xx xx PORT 本地用户用来接收消息的IP地址
1 byte 04 X2 *Unknown
2 bytes 00 00 X3 *Unknown
2 bytes xx xx CMD_TYPE 标识消息是原始消息还是回复
4 bytes xx xx xx xx X4 *Unknown (校验和?序列号?)
TYPE字段跟 RECEIVE_MESSAGE 里的一样. CMD_TYPE 有两种可能取值:
10 00 = 这是一条原始的,新消息
00 00 = 这是一条回复消息
自动回复作为新消息的确认被发送,通常为一条空消息,如果远程用户处于Away或者DND
模式,则其回复消息被发送。X4字段有点狡猾,经常在 00 FF FF FF 和 FF FF FF FF 之间,
但是确切的功能还不知道。

补充:
Command 0x0104 - 通过服务器接收在线消息
0x0002 - ICQ Version
0x0104 - 命令
0x???? - 序列号
0x???????? - 发送者的 UIN.
0x?? - Type (跟 0x00DC 里的一样)
0x?? - 消息的长度,包括NULL.
消息,0x00 结束。
Command 0x00e6 - 服务器上没有更多的离线消息了(服务器发送的).
Command 0x0442 - 删除所有离线消息 (客户端发送).
Command 64 00,口令错误
在发送了LOGIN后,服务器返回的命令。
Command: 0x0028 (28 00 in intel order)
Version: 2
Data: 4b 20 ab 00 (Wich happens to be my UIN...)
服务器发出的,客户端已经离线了
ywbby 2000-09-22
  • 打赏
  • 举报
回复
attention
King 2000-09-13
  • 打赏
  • 举报
回复
一对一聊天可以参考DELPHI的例子。

事实上我觉得ICQ一类的软件最重要是速度和安全性的平衡。
netsong 2000-09-12
  • 打赏
  • 举报
回复
呵呵,用tcp和udp都可以实现。关键是服务端的负载、均衡、吞吐量等的能力。
icq, oicq设计得很好。
到VC里面看看,正在讨论oicq呢。

16,466

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧