nodejs 封包 访问udp

nodejs 写的 基于UDP 的client,将数据封装成二进制,访问udp server:

var rawCode = new Buffer("54ef43456565","hex");
console.log(rawCode)

//这个函数用来转换大小端(swap endian between little and big)
function swapBytes(buffer) {
  var l = buffer.length;
  if (l & 0x01) {
    throw new Error('Buffer length must be even');
  }
  for (var i = 0; i < l; i += 2) {
    var a = buffer[i];
    buffer[i] = buffer[i+1];
    buffer[i+1] = a;
  }
  return buffer; 
}


function cppString(str,len){

	this.str = "";
	if(str.length > len-1){
		this.str = str.slice(0,len-1);
	}else{
		this.str = str;
	}
	this.str += "\0";
	
	this.byteLen = len;
	this.buffer = new Buffer(this.byteLen);
	this.length = this.buffer.length;
	
	this.process();
}

cppString.prototype.toString = function(){
	return this.buffer.toString();
}

cppString.prototype.getLength = function(){
	return this.buffer.length;
}

cppString.prototype.process = function(){
	this.buffer.fill(0);
	this.buffer.write(this.str);
	/*for(var i=this.str.length;i < this.buffer.length;i++){
		this.buffer[i] = 0x00;
	}*/
	//this.buffer = swapBytes(this.buffer);
	//console.log(this.buffer)
}




function cppNum(num,intType){

	this.num = num;
	
	this.buffer = null;
	this.value = null;
	this.numArray = null;
	this.byteLen = null
	this.intType = intType;
	
	switch(this.intType){
		case "uint8":
			this.numArray = new Uint8Array([num]);  
			this.byteLen = 1;
		break;
		case "uint16":
			this.numArray = new Uint16Array([num]);  
			this.byteLen = 2;
		break;
		case "uint32":
			this.numArray = new Uint32Array([num]); 
			this.byteLen = 4;
		break;
		case "int8":
			this.numArray = new Int8Array([num]);  
			this.byteLen = 1;
		break;
		case "int16":
		    this.numArray = new Int16Array([num]);  
			this.byteLen = 2;
			break;
		case "int32":
			this.numArray = new Int32Array([num]);  
			this.byteLen = 4;
			break;
		default:
		break;
	}


	this.process();
}


cppNum.prototype.process = function(){

	this.value = this.numArray[0];
	this.buffer = new Buffer(this.byteLen);
	this.buffer.fill(0);//clear all the buffer
	
	switch(this.intType){
		case "uint8"://uint8
			this.buffer.writeUInt8(this.value,0);//little endian (按小端对齐)
			break;
		case "uint16"://uint16
			this.buffer.writeUInt16LE(this.value,0);//little endian (按小端对齐)
			break;
		case "uint32"://uint32
			this.buffer.writeUInt32LE(this.value,0);//little endian (按小端对齐)
			break;
		case "int8"://int8
			this.buffer.writeInt8(this.value,0);//little endian (按小端对齐)
			break;
		case "int16"://int16
			this.buffer.writeInt16LE(this.value,0);//little endian (按小端对齐)
			break;
		case "int32"://int32
			this.buffer.writeInt32LE(this.value,0);//little endian (按小端对齐)
			break;
		default:break;
	}
	
	//console.log(this.buffer);
	//var rawValue = this.value.toString();
	
	//for(var i=0;i < this.byteLen;i++){
		//this.buffer[i] = rawValue >> (8*i);
	//}
	
	//this.buffer = swapBytes(this.buffer);	
}



function pack(listObj){

	var listBuffer = new Array();
	this.length =0;
	for(var i=0;i < listObj.length;i++){
		listBuffer.push(listObj[i].buffer);
		this.length += listObj[i].byteLen;
	}
	this.buffer = Buffer.concat(listBuffer);
}

console.log("--------start send data by udp protocal----------------");

var dgram = require("dgram");
var socket = dgram.createSocket("udp4");
socket.bind(function () {
  socket.setBroadcast(true);
});

var name = new cppString("zhengjinwei zhengjinwei zhengjinwei",20);//如果长度超过20,自动截取前19个,最后一个是"\0"
var sex = new cppString("male",10);
var age = new cppNum(2147483647,"int32");
var data = new cppString("this is a demo for using js to pack net work package to binary type",100);

var msg = new pack([name,sex,data,age]);

socket.send(msg.buffer,0, msg.length, 21210, '127.0.0.1', function(err, bytes) {
  socket.close();
});




下面是c++写的基于 UDP 的 server:

// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include 
#include 
#pragma comment(lib,"ws2_32.lib")

#pragma pack(push)
#pragma pack(1)

//注意:要按一字节对齐,否者数据长度有错
struct SMsg
{
	char name[20];
	char sex[10];
	char strMsg[100];
	int age;
};


void main() 
{ 

	int value =sizeof(SMsg);

	printf("%d",value);

	WORD wVersionRequested; 
	WSADATA wsaData; 
	int err; 

	wVersionRequested=MAKEWORD(1,1); 

	err = WSAStartup(wVersionRequested, &wsaData); 
	if (err != 0) 
	{ 

		return; 
	} 

	if (LOBYTE(wsaData.wVersion)!=1 || 
		HIBYTE(wsaData.wVersion)!=1) 
	{ 
		WSACleanup(); 
		return; 
	} 

	SOCKET sockSrv=socket(AF_INET,SOCK_DGRAM,0);
	SOCKADDR_IN addrSrv;
	addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
	addrSrv.sin_family=AF_INET;
	addrSrv.sin_port=htons(21210);

	bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));

	SOCKADDR_IN addrClient;
	int len=sizeof(SOCKADDR);

	while(true){
		char recvBuf[400];

		recvfrom(sockSrv,recvBuf,400,0,(SOCKADDR*)&addrClient,&len);

		SMsg *pmsg = (SMsg*)(recvBuf);

		printf("name=%s,age=%d,sex=%s,data=%s\n",pmsg->name,pmsg->age,pmsg->sex,pmsg->strMsg);
	}
	
	closesocket(sockSrv);
	WSACleanup();
}

#pragma  pack(pop)

 

 nodejs 封包 访问udp_第1张图片



上面那个node写的client不够好,再次进行封装,如下:

function cppString(str,len){

	this.str = "";
	if(str.length > len-1){
		this.str = str.slice(0,len-1);
	}else{
		this.str = str;
	}
	this.str += "\0";
	
	this.byteLen = len;
	this.buffer = new Buffer(this.byteLen);
	this.length = this.buffer.length;
	
	this.process();
}

cppString.prototype.toString = function(){
	return this.buffer.toString();
}

cppString.prototype.getLength = function(){
	return this.buffer.length;
}

cppString.prototype.process = function(){
	this.buffer.fill(0);
	this.buffer.write(this.str);
	/*for(var i=this.str.length;i < this.buffer.length;i++){
		this.buffer[i] = 0x00;
	}*/
}




function cppNum(num,intType){

	this.num = num;
	
	this.buffer = null;
	this.value = null;
	this.numArray = null;
	this.byteLen = null
	this.intType = intType;
	
	switch(this.intType){
		case "uint8":
			this.numArray = new Uint8Array([num]);  
			this.byteLen = 1;
		break;
		case "uint16":
			this.numArray = new Uint16Array([num]);  
			this.byteLen = 2;
		break;
		case "uint32":
			this.numArray = new Uint32Array([num]); 
			this.byteLen = 4;
		break;
		case "int8":
			this.numArray = new Int8Array([num]);  
			this.byteLen = 1;
		break;
		case "int16":
		    this.numArray = new Int16Array([num]);  
			this.byteLen = 2;
			break;
		case "int32":
			this.numArray = new Int32Array([num]);  
			this.byteLen = 4;
			break;
		default:
		break;
	}
	this.process();
}


cppNum.prototype.process = function(){

	this.value = this.numArray[0];
	this.buffer = new Buffer(this.byteLen);
	this.buffer.fill(0);//clear all the buffer
	
	switch(this.intType){
		case "uint8"://uint8
			this.buffer.writeUInt8(this.value,0);//little endian (按小端对齐)
			break;
		case "uint16"://uint16
			this.buffer.writeUInt16LE(this.value,0);//little endian (按小端对齐)
			break;
		case "uint32"://uint32
			this.buffer.writeUInt32LE(this.value,0);//little endian (按小端对齐)
			break;
		case "int8"://int8
			this.buffer.writeInt8(this.value,0);//little endian (按小端对齐)
			break;
		case "int16"://int16
			this.buffer.writeInt16LE(this.value,0);//little endian (按小端对齐)
			break;
		case "int32"://int32
			this.buffer.writeInt32LE(this.value,0);//little endian (按小端对齐)
			break;
		default:break;
	}
}





function msg(host,port){
	this.listBuffer = new Array();;
	this.length = 0;
	
	this.port = port;
	this.host = host;
}

msg.prototype.push_uint8 = function(value){
	var uint8Value = new cppNum(value,"uint8");
	this.listBuffer.push(uint8Value.buffer);
	this.length += uint8Value.byteLen;
}
msg.prototype.push_int8 = function(value){
	var int8Value = new cppNum(value,"int8");
	this.listBuffer.push(int8Value.buffer);
	this.length += int8Value.byteLen;
}
msg.prototype.push_uint16 = function(value){
	var uint16Value = new cppNum(value,"uint16");
	this.listBuffer.push(uint16Value.buffer);
	this.length += uint16Value.byteLen;
}
msg.prototype.push_int16 = function(value){
	var int16Value = new cppNum(value,"int16");
	this.listBuffer.push(int16Value.buffer);
	this.length += int16Value.byteLen;
}
msg.prototype.push_uint32 = function(value){
	var uint32Value = new cppNum(value,"uint32");
	this.listBuffer.push(uint32Value.buffer);
	this.length += uint32Value.byteLen;
}
msg.prototype.push_int32 = function(value){
	var int32Value = new cppNum(value,"int32");
	this.listBuffer.push(int32Value.buffer);
	this.length += int32Value.byteLen;
}

msg.prototype.push_string = function(strValue,len){
	var strValue = new cppString(strValue,len);
	this.listBuffer.push(strValue.buffer);
	this.length += strValue.byteLen;
}

msg.prototype.push_char = function(strChar){
	var strValue = new cppString(strValue,2);
	this.listBuffer.push(strValue.buffer);
	this.length += strValue.byteLen;
}
msg.prototype.send = function(){
	if(this.listBuffer.length > 0){
		var dgram = require("dgram");
		var socket = dgram.createSocket("udp4");
		socket.bind(function () {
			socket.setBroadcast(true);
		});
		var buffer = Buffer.concat(this.listBuffer);
		socket.send(buffer,0, this.length, this.port,this.host, function(err, bytes) {
			socket.close();
		});
	}
}


console.log("--------start send data by udp protocal----------------");

var messgae = new msg("127.0.0.1",21210);

messgae.push_string("zhengjinwei",20);
messgae.push_string("male",10);
messgae.push_string("my name is zhengjinwei",100);
messgae.push_int32(212121212);

messgae.send();



参考网站:http://stackoverflow.com/questions/14730980/nodejs-write-64bit-unsigned-integer-to-buffer


你可能感兴趣的:(node.js技术)