eMule Protocol
Overview
A client uses a single TCP connection to an eMule server to logging into the network, getting information about desired files and available clients.
The eMule client also uses serveral hundreds of TCP connection to other clients which are used to upload and download files.
Client ID
4-byte identifier provided by the server at client-server connection handshake. There is two kind of Client ID: HighID and LowID.
LowID
Server assigns a client with a LowID when the client can’t accept incoming connections. LowID always lower than 16777216.
HighID
Assuming client host IP is X.Y.Z.W, then HighID is X+2(8)*Y+2(16)*Z+2(24)*W.
User ID
For support credit system and it is 128 bit (16 byte) GUID (concatenating randon numbers), 6th and 15th byte are 14 and 111 respectively.
File hash
Files are uniquely identified by a 128 bit (16 byte) GUID hash calculated by the client and based on the file’s contents. The GUID is calculated by applying the MD4 algorithm on the file’s data.
Client-server connection establishment
1 Client-server建立连接
2 Client向Server发送Login请求(Login Message)
3 Server分配一个ID给Client(是否为HighID取决于4-7)。
4 Server向Client发起一个TCP连接(端口为Client设置的端口);
5 Server向Client发送一个Hello消息;
6 诺Client可以收到Incoming connection,则回复Server一个Hello answer消息,这一步直接决定Server是否分配一个HighID给Client;
7 断开Server-client的TCP连接。
其中2、3、4、5、6将被应用层处理。
File search
Client向Server发送一个File search消息,Server回复Client一个Search result消息。
Tag format
Login、File search和Search result等消息中会包含多个Tag。一般Tag由Type、Name和Value三部分组成,格式如下:
[Type + Name + Value]
Type长度固定为1byte,表示Tag类型;
Name格式为[2byte for length of name in byte + name(length)]
Value格式需要根据Type类型而定。如果Type为0x02(String型),则Value格式为
[2byte for length of value in byte + value(length)];如果Type为其他类型,则Value长度为其他类型相应的所占内存大小。常见Type类型对照表如下:
类型值 |
类型名称 |
类型大小(byte) |
0x01 |
Hash |
16 |
0x02 |
String |
Variable |
0x03 |
UINT32 |
4 |
0x04 |
Float32 |
4 |
0x05 |
Bool |
|
0x06 |
boolarray |
|
0x07 |
BLOB |
|
0x08 |
Uint16 |
2 |
0x09 |
Uint8 |
1 |
0x0A |
BSOB |
|
0X0B |
Uint64 |
8 |
Message format
Login
字段名称 |
大小(byte) |
默认值 |
备注 |
协议 |
1 |
0xE3 |
|
大小 |
4 |
|
与字节为单位的消息长度,不包含大小字段和协议字段 |
类型 |
1 |
0x01 |
OP_LOGINREQUEST操作码 |
User Hash |
16 |
|
用户hash |
Client ID |
4 |
0 |
|
TCP端口 |
2 |
4662 |
在eMule选项设置里设置的TCP端口号 |
Tag数量 |
4 |
4 |
接下来的Tag的数量 |
用户昵称Tag |
varies |
|
用户的昵称,这个tag是String类型,tag name为0x01 |
版本Tag |
8 |
0x3C |
Client支持的eDonkey版本号,此tag为Uint32类型,tag name为0x11 |
Flags Tag |
8 |
0x01 |
此tag为Uint32类型,tag name为0x20 |
eMule Version Tag |
8 |
|
此tag为Uint32类型,tag name为0xFB |
ID change
字段名称 |
大小(byte) |
默认值 |
备注 |
协议 |
1 |
0xE3 |
|
大小 |
4 |
|
与字节为单位的消息长度,不包含大小字段和协议字段 |
类型 |
1 |
0x40 |
OP_IDCHANGE操作码 |
Client ID |
4 |
NA |
Server分配给Client的ID |
TCP connection bitmap |
4 |
0x00001 |
目前只有1bit有意义,设置为1表示服务器支持压缩 |
Search request
字段名称 |
大小(byte) |
默认值 |
备注 |
协议 |
1 |
0xE3 |
|
大小 |
4 |
|
与字节为单位的消息长度,不包含大小字段和协议字段 |
类型 |
1 |
0x16 |
OP_SEARCHREQUEST操作码 |
经解析的查询字符串 |
Varies |
NA |
[0x01] + [length in byte] + [parsed string] 1 byte 2 byte |ß length à| |
*此Search request消息格式为最简化的格式,详见eMule protocol中的解释。
Search result
字段名称 |
大小(byte) |
默认值 |
备注 |
协议 |
1 |
0xE3 |
|
大小 |
4 |
|
与字节为单位的消息长度,不包含大小字段和协议字段 |
类型 |
1 |
0x33 |
OP_LOGINREQUEST操作码 |
结果条数 |
4 |
NA |
搜索到的结果的条数 |
Result list |
Varies |
NA |
搜索结果列表 |
Search result list item format
字段名称 |
大小(byte) |
默认值 |
备注 |
文件Hash |
16 |
NA |
Hash值,唯一表示文件的ID |
Client ID |
4 |
NA |
持有此文件的用户ID |
Client port |
2 |
NA |
持有此文件的用户的TCP端口 |
Tag数量 |
4 |
NA |
下面将要描述的Tag数量 |
Tag list |
varies |
NA |
下面将要描述的Tag列表 |
这里的Tag由以下几部分组成:1byte的Tag类型 + 文件属性类型 +属性值。
此时的Tag类型值不同于前面说将,它由Server发送Client,一般都为0x8X,在处理时要先把此值与0x80做逻辑与操作,等到的值和前面的Tag类型列表对应起来,属性值的长度受Tag类型约束。如Tag类型为0x82,和0x80逻辑与操作后,得到的值为0x02,即为String型,则此Tag为
[0x82][文件属性类型][String length(2byte)][stringValue(length)]
文件属性类型见下表:
属性名 |
Tag name |
Tag Type |
备注 |
文件名 |
0x01 |
String |
|
文件大小 |
0x02 |
Uint32 |
|
文件类型 |
0x03 |
String |
|
文件格式 |
0x04 |
String |
|
来源数 |
0x15 |
Uint8 |
此文件可用的下载源数目 |
完成来源 |
0x30 |
Uint8 |
|
Artist |
String ”Artist” |
String |
|
Album |
String ”Album” |
String |
|
Title |
String ”Title” |
String |
|
Length |
String ”length” |
Integer |
|
Bitrate |
String ”bitrate” |
Integer |
|
Codec |
String ”codec” |
Integer |
|