\u6211\u4eec\u770b\u5230\u521b\u5efa\u4e00\u4e2audp\u670d\u52a1\u5668\u5f88\u7b80\u5355\uff0c\u9996\u5148\u7533\u8bf7\u4e00\u4e2asocket\u5bf9\u8c61\uff0c\u5728nodejs\u4e2d\u548c\u64cd\u4f5c\u7cfb\u7edf\u4e2d\u4e00\u6837\uff0csocket\u662f\u5bf9\u7f51\u7edc\u901a\u4fe1\u7684\u4e00\u4e2a\u62bd\u8c61\uff0c\u6211\u4eec\u53ef\u4ee5\u628a\u4ed6\u7406\u89e3\u6210\u5bf9\u4f20\u8f93\u5c42\u7684\u62bd\u8c61\uff0c\u4ed6\u53ef\u4ee5\u4ee3\u8868tcp\u4e5f\u53ef\u4ee5\u4ee3\u8868udp\u3002<\/strong><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/p>\n
\u6211\u4eec\u4ece\u4e00\u4e2a\u4f7f\u7528\u4f8b\u5b50\u5f00\u59cb\u770b\u770budp\u6a21\u5757\u7684\u5b9e\u73b0\u3002<\/p>\n
\r\nconst dgram = require('dgram'); \r\n\/\/ \u521b\u5efa\u4e00\u4e2asocket\u5bf9\u8c61 \r\nconst server = dgram.createSocket('udp4'); \r\n\/\/ \u76d1\u542cudp\u6570\u636e\u7684\u5230\u6765 \r\nserver.on('message', (msg, rinfo) => { \r\n \/\/ \u5904\u7406\u6570\u636e});\/\/ \u7ed1\u5b9a\u7aef\u53e3 \r\nserver.bind(41234); \r\n<\/pre>\n\u6211\u4eec\u770b\u5230\u521b\u5efa\u4e00\u4e2audp\u670d\u52a1\u5668\u5f88\u7b80\u5355\uff0c\u9996\u5148\u7533\u8bf7\u4e00\u4e2asocket\u5bf9\u8c61\uff0c\u5728nodejs\u4e2d\u548c\u64cd\u4f5c\u7cfb\u7edf\u4e2d\u4e00\u6837\uff0csocket\u662f\u5bf9\u7f51\u7edc\u901a\u4fe1\u7684\u4e00\u4e2a\u62bd\u8c61\uff0c\u6211\u4eec\u53ef\u4ee5\u628a\u4ed6\u7406\u89e3\u6210\u5bf9\u4f20\u8f93\u5c42\u7684\u62bd\u8c61\uff0c\u4ed6\u53ef\u4ee5\u4ee3\u8868tcp\u4e5f\u53ef\u4ee5\u4ee3\u8868udp\u3002\u6211\u4eec\u770b\u4e00\u4e0bcreateSocket\u505a\u4e86\u4ec0\u4e48\u3002<\/p>\n
\r\nfunction createSocket(type, listener) { \r\n return new Socket(type, listener); \r\n} \r\n \r\nfunction Socket(type, listener) { \r\n EventEmitter.call(this); \r\n let lookup; \r\n let recvBufferSize; \r\n let sendBufferSize; \r\n \r\n let options; \r\n if (type !== null && typeof type === 'object') { \r\n options = type; \r\n type = options.type; \r\n lookup = options.lookup; \r\n recvBufferSize = options.recvBufferSize; \r\n sendBufferSize = options.sendBufferSize; \r\n } \r\n const handle = newHandle(type, lookup); \r\n this.type = type; \r\n if (typeof listener === 'function') \r\n this.on('message', listener); \r\n \r\n this[kStateSymbol] = { \r\n handle, \r\n receiving: false, \r\n bindState: BIND_STATE_UNBOUND, \r\n connectState: CONNECT_STATE_DISCONNECTED, \r\n queue: undefined, \r\n reuseAddr: options && options.reuseAddr, \/\/ Use UV_UDP_REUSEADDR if true. \r\n ipv6Only: options && options.ipv6Only, \r\n recvBufferSize, \r\n sendBufferSize \r\n };} \r\n<\/pre>\n\u6211\u4eec\u770b\u5230\u4e00\u4e2asocket\u5bf9\u8c61\u662f\u5bf9handle\u7684\u4e00\u4e2a\u5c01\u88c5\u3002\u6211\u4eec\u770b\u770bhandle\u662f\u4ec0\u4e48\u3002<\/p>\n
\r\nfunction newHandle(type, lookup) { \r\n \/\/ \u7528\u4e8edns\u89e3\u6790\u7684\u51fd\u6570\uff0c\u6bd4\u5982\u6211\u4eec\u8c03send\u7684\u65f6\u5019\uff0c\u4f20\u7684\u662f\u4e00\u4e2a\u57df\u540d \r\n if (lookup === undefined) { \r\n if (dns === undefined) { \r\n dns = require('dns'); \r\n } \r\n \r\n lookup = dns.lookup; \r\n } \r\n \r\n if (type === 'udp4') { \r\n const handle = new UDP(); \r\n handle.lookup = lookup4.bind(handle, lookup); \r\n return handle; \r\n } \r\n \/\/ \u5ffd\u7565ipv6\u7684\u5904\u7406} \r\n<\/pre>\nhandle\u53c8\u662f\u5bf9UDP\u6a21\u5757\u7684\u5c01\u88c5\uff0cUDP\u662fc++\u6a21\u5757\uff0c\u6211\u4eec\u770b\u770b\u8be5c++\u6a21\u5757\u7684\u5b9a\u4e49\u3002<\/p>\n
\r\n\/\/ \u5b9a\u4e49\u4e00\u4e2av8\u51fd\u6570\u6a21\u5757 \r\nLocal t = env->NewFunctionTemplate(New); \r\n \/\/ t\u65b0\u5efa\u7684\u5bf9\u8c61\u9700\u8981\u989d\u5916\u62d3\u5c55\u7684\u5185\u5b58 \r\n t->InstanceTemplate()->SetInternalFieldCount(1); \r\n \/\/ \u5bfc\u51fa\u7ed9js\u5c42\u4f7f\u7528\u7684\u540d\u5b57 \r\n Local udpString = FIXED_ONE_BYTE_STRING(env->isolate(), \"UDP\"); \r\n t->SetClassName(udpString); \r\n \/\/ \u5c5e\u6027\u7684\u5b58\u53d6\u5c5e\u6027 \r\n enum PropertyAttribute attributes = static_cast(ReadOnly | DontDelete); \r\n \r\n Local signature = Signature::New(env->isolate(), t); \r\n \/\/ \u65b0\u5efa\u4e00\u4e2a\u51fd\u6570\u6a21\u5757 \r\n Local get_fd_templ = \r\n FunctionTemplate::New(env->isolate(), \r\n UDPWrap::GetFD, \r\n env->as_callback_data(), \r\n signature); \r\n \/\/ \u8bbe\u7f6e\u4e00\u4e2a\u8bbf\u95ee\u5668\uff0c\u8bbf\u95eefd\u5c5e\u6027\u7684\u65f6\u5019\uff0c\u6267\u884cget_fd_templ\uff0c\u4ece\u800c\u6267\u884cUDPWrap::GetFD \r\n t->PrototypeTemplate()->SetAccessorProperty(env->fd_string(), \r\n get_fd_templ, \r\n Local<\/functiontemplate>(), \r\n attributes); \r\n \/\/ \u5bfc\u51fa\u7684\u51fd\u6570 \r\n env->SetProtoMethod(t, \"open\", Open); \r\n \/\/ \u5ffd\u7565\u4e00\u7cfb\u5217\u51fd\u6570 \r\n \/\/ \u5bfc\u51fa\u7ed9js\u5c42\u4f7f\u7528 \r\n target->Set(env->context(), \r\n udpString, \r\n t->GetFunction(env->context()).ToLocalChecked()).Check(); \r\n<\/functiontemplate><\/signature><\/propertyattribute><\/string><\/functiontemplate><\/pre>\n\u5728c++\u5c42\u901a\u7528\u903b\u8f91\u4e2d\u6211\u4eec\u8bb2\u8fc7\u76f8\u5173\u7684\u77e5\u8bc6\uff0c\u8fd9\u91cc\u5c31\u4e0d\u8be6\u7ec6\u8bb2\u8ff0\u4e86\uff0c\u5f53\u6211\u4eec\u5728js\u5c42new UDP\u7684\u65f6\u5019\uff0c\u4f1a\u65b0\u5efa\u4e00\u4e2ac++\u5bf9\u8c61\u3002<\/p>\n
\r\nUDPWrap::UDPWrap(Environment* env, Local