通過EPMD來獲取Erlang Node的Port

2021-05-21 20:30:59 字數 2630 閱讀 4781

在這裡,主要是簡單的介紹一下,客戶端與服務節點通訊前是如何傳送請求資訊到epmd,並獲取服務節點的port後,再與服務節點實現tcp通訊的。

客戶端是通過埠號4369來實現與epmd通訊的。在傳送請求資料時,每個請求中的前兩個位元組是代表本次請求的內容長度(如a圖)。在請求獲取服務節點埠號中,請求內容則是占有乙個位元組的請求識別符號和服務節點名稱(b圖)。

a、請求資料格式2n

length

request

b、請求內容格式1n

122nodename

當epmd接受請求後,返回響應資訊,響應資訊的第乙個位元組是乙個識別符號119,第二個位元組是返回結果,如果結果大於0,則說明未找到對應服務節點;結果等於0,則後面接著的是對應的服務節點資訊。

a、返回結果大於0,返回的資料格式11

119result

b、返回結果等於0,返回的資料格式11

2112

22nlen

2elen

119result

portno

nodetype

protocol

highestversion

lowestversion

nlen

nodename

elen

extra

上面的所有第一行中的數字都是表示的位元組數。

通過上面的簡單介紹,已經可以初步了解其實現原理了,為了更好的理解,下面是用c#來模擬實現。

class epmd

private string   _alive;

private string   _host;

private string   _node;

public  epmd(system.string nodename)

int i = nodename.indexof((system.char)'@', 0);

if (i < 0)

_alive = nodename;

_host = null;

else

_alive = nodename.substring(0, (i) - (0));

_host = nodename.substring(i + 1, (nodename.length) - (i + 1));

if (_alive.length > 0xff)

_alive = _alive.substring(0, (0xff) - (0));

_node = _alive + "@" + _host;

public int getport()

tcpclient client = new tcpclient(_host, 4369);

networkstream stream = client.getstream();

byte buf = new byte[3 + _alive.length];

// 前兩個位元組寫入本次請求資料長度

buf[0] = 0;

buf[1] = (byte)(_alive.length + 1);

//第三個位元組寫入本次請求識別符號

buf[2] = 122;

// 寫入請求的節點名稱

byte data = system.text.encoding.utf8.getbytes(_alive);

for (int i = 0; i < data.length; i++)

buf[i + 3] = data[i];

// 向epmd傳送請求資料

stream.write(buf, 0, buf.length);

byte tmpbuf = new byte[100];

// 獲取響應資料

int n = stream.read(tmpbuf, 0, 100);

// n小於0,則請求失敗

if (n < 0)

client.close();

console.writeline("在主機上未獲取到epmd相應", _host);

return 0;

memorystream mem = new memorystream(tmpbuf);

// 第一位,獲取響應識別符號

int port_resp = mem.readbyte();

// 第二位,獲取響應結果

int result = mem.readbyte();

// 返回與節點對應的埠資訊

if (result == 0)

// 讀取2個位元組資料,獲取埠號

byte b = new byte[2];

mem.read(b, 0, b.length);

return ((((int)b[0] << 8) & 0xff00) + (((int)b[1]) & 0xff));

return 0;

static void main(string args)

epmd test = new epmd("servernode@liyiqun");

int port = test.getport();

console.readkey(true);

如果不確定自己獲取的埠號是否正確,還可以在erlang shell中通過執行net_adm:names().函式來驗證是否一致。

Erlang的erl與epmd的區別與聯絡

2 erl是啟動erlang虛擬機器的命令。3 從實際操作的角度看,只要執行erl選項包含 name 或者 sname就會自動啟動epmd和net kernel。如果由於意外關閉了epmd程序,可以通過 usr local lib erlang erts 6.0 bin epmd daemon 啟動...

如何通過subId來獲取phoneId

androidl中使用一張資料表來儲存sim卡資訊 telephony.db中有一張記錄sim卡資訊的表,siminfo create table siminfo id integer primary key autoincrement,icc id text not null,sim id int...

js 通過arguments來獲取指定引數

通過訪問arguments物件的length屬性可以獲取有多少個引數傳遞給了函式。如 每次被呼叫的時候,輸出傳入其中的引數個數 function doadd doadd 0 doadd 1 1 doadd 1,2 2 doadd string 1 2 由此,可以利用這一點,函式能夠接受任意個引數引數...