2012-11-04 97 views

回答

4

這是我的getsockopt:後期

var ffi = require('ffi'); 
var net = require('net'); 
var StructType = require('ref-struct'); 
var ref = require('ref'); 

var current = ffi.Library(null, { 
    'getsockopt': [ 'int', [ 'int', 'int', 'int', 'pointer', 'pointer']], 
    'ntohs': ['uint16', ['uint16']], 
// const char *inet_ntop(int af, const void *src, char *dst, socklen_t size); 

}); 

var SOL_IP = 0; 
var SO_ORIGINAL_DST = 80; 
var AF_INET = 2; 

var sockaddr_in = StructType([ 
    ['int16', 'sin_family'], 
    ['uint16', 'sin_port'], 
    ['uint32', 'sin_addr'], 
    ['uint32', 'trash1'], 
    ['uint32', 'trash2'], 
]); 

function get_original_dst(client) { 
    var dst = new sockaddr_in; 
    var dstlen = ref.alloc(ref.types.int, sockaddr_in.size); 
    var r = current.getsockopt(client._handle.fd, SOL_IP, SO_ORIGINAL_DST, dst.ref(), dstlen); 
    if (r === -1) 
     throw new Error("getsockopt(SO_ORIGINAL_DST) error"); 
    if (dst.sin_family !== AF_INET) 
     throw new Error("getsockopt(SO_ORIGINAL_DST) returns unknown family: " + dst.sin_family); 

    // TODO: inet_ntop. inet_ntoa is _UNSAFE_ 
    var ipaddr = dst.ref(); ipaddr = ipaddr[4] + "." + ipaddr[5] + "." + ipaddr[6] + "." + ipaddr[7]; 

    return [ipaddr, current.ntohs(dst.sin_port)]; 
} 

module.exports.get_original_dst = get_original_dst; 
-1

種類,但這裏是故宮一個pacakge https://www.npmjs.com/package/net-keepalive

提供像TCP_KEEPIDLE,TCP_KEEPINTVL,TCP_KEEPCNT

套接字選項的高級別訪問
var Net = require('net') 
    , NetKeepAlive = require('net-keepalive') 
; 

// Create a TCP Server 
var srv = Net.createServer(function(s){> 
    console.log('Connected %j', s.address()) 
    // Doesn't matter what it does 
    s.pipe(s) 
}); 

// Start on some port 
srv.listen(1337, function(){ 
    console.log('Listening on %j', srv.address()) 
}); 

// Connect to that server 
var s = Net.createConnection({port:1337}, function(){ 
    console.log('Connected to %j', s.address()) 

    //IMPORTANT: KeepAlive must be enabled for this to work 
    s.setKeepAlive(true, 1000) 

    // Set TCP_KEEPINTVL for this specific socket 
    NetKeepAlive.setKeepAliveInterval(s, 1000) 

    // and TCP_KEEPCNT 
    NetKeepAlive.setKeepAliveProbes(s, 1) 
}); 
3

我擴大在評論留下b y socketpair其中顯示getsockopt。您可以通過使用ffiref做到這一點。我已將其重新格式化,以便於輕鬆操作。

我編輯我的意見,因爲我不得不作出一些改變,使在Linux和Win32代碼工作。我不得不創建一個​​獲得套接字句柄,並把它傳遞給setsockopt。要知道,Linux和Windows可能有不同的值,套接字選項

編輯:這裏有一個清理件的生產代碼我使用的:

var net = require("net"); 
var ffi = require("ffi"); 
var ref = require("ref"); 
var getSocketHandleAddress; 

var SOL_SOCKET = 0x1; 
var SO_OOBINLINE = 0xA; 
var _setsockopt; 

if (process.platform == "win32") { 
    SOL_SOCKET = 0xffff; 
    SO_OOBINLINE = 0x0100; 
} 

var setSocketOption = function (handle, level, option, value) { 
    if (!_setsockopt) { 
    var library; 
    var paramTypes; 
    if (process.platform === "win32") { 
     library = "ws2_32.dll"; 
     paramTypes = [ 
     ref.types.int, 
     ref.types.int, 
     ref.types.int, 
     ref.refType(ref.types.void), 
     ref.types.int 
     ]; 
    } else { 
     paramTypes = [ 
     ref.types.int, 
     ref.types.int, 
     ref.types.int, 
     ref.refType(ref.types.void), 
     ref.refType(ref.types.int) 
     ]; 
    } 
    var lib = new ffi.DynamicLibrary(library); 
    _setsockopt = ffi.ForeignFunction(
     lib.get("setsockopt"), 
     ref.types.int, 
     paramTypes); 
    } 
    var refType; 
    var length; 
    if (typeof value === "boolean") { 
    refType = ref.types.bool; 
    } else { 
    refType = ref.types.int; 
    } 
    if (process.platform !== "win32") { 
    return _setsockopt(
     handle.fd, 
     level, 
     option, 
     ref.alloc(refType, value), 
     ref.alloc(ref.types.int, refType.size) 
    ); 
    } 
    if (!getSocketHandleAddress) { 
    getSocketHandleAddress = require("getsockethandleaddress"); 
    } 
    return _setsockopt(
    getSocketHandleAddress.getAddress(handle), 
    level, 
    option, 
    ref.alloc(refType, value), 
    refType.size 
); 

}; 

var tcpserver = net.createServer(function (socket) { 
    var ret = setSocketOption(socket._handle, SOL_SOCKET, SO_OOBINLINE, true); 
    if (ret !== 0) { 
    console.error("OOB Inline socket option failed: " + ret); 
    } 
}); 
+0

你如何socket._handle和socket._handle .fd不爲空? –

+0

@SarenArterius在套接字連接到TCP服務器後調用它。例如'net.createServer(function(socket){setsockopt(...);});' – ShortFuse

+0

@ShortFuse函數的簽名似乎不正確。看起來它是用getsockopt並沒有setsockopt的 – Pavel