Nodejs socket.write() 可否指定 remoteaddress & port?
Nodejs socket.write() 可否指定 remoteaddress & port?
因为要选择不同客户端发送数据给他,remoteaddress & port 已经存在数据,需要发送时要指定远程的地址和端口(当然,数据库会实时更新客户的地址和端口),查手册socket.write 未提及 指定地址和端口的选项。
Node.js Socket.write() 是否可以指定 remoteAddress 和 port?
问题描述
在使用 Node.js 的 net
模块进行网络编程时,我们可能会遇到需要向特定客户端发送数据的情况。假设我们已经有客户端的 remoteAddress
和 port
信息,并希望在发送数据时明确指定这些信息。然而,在查阅 socket.write()
方法的手册时,没有找到直接指定 remoteAddress
和 port
的选项。
解决方案
实际上,socket.write()
方法本身并不支持直接指定 remoteAddress
和 port
。这是因为 socket.write()
是用于在已建立连接的套接字上发送数据,而 remoteAddress
和 port
应该在套接字建立连接时指定。
但是,你可以通过创建一个新的套接字连接到目标 remoteAddress
和 port
,然后使用 socket.write()
发送数据。以下是一个示例代码:
const net = require('net');
// 假设我们有以下远程地址和端口信息
const remoteAddress = '127.0.0.1';
const remotePort = 8080;
// 创建一个新的套接字连接
const socket = new net.Socket();
// 连接到远程地址和端口
socket.connect(remotePort, remoteAddress, () => {
console.log(`Connected to ${remoteAddress}:${remotePort}`);
// 在连接成功后发送数据
const dataToSend = 'Hello, client!';
socket.write(dataToSend);
});
// 处理错误
socket.on('error', (err) => {
console.error(`Socket error: ${err.message}`);
});
// 监听数据接收事件
socket.on('data', (data) => {
console.log(`Received data: ${data.toString()}`);
});
// 监听连接关闭事件
socket.on('close', () => {
console.log('Connection closed');
});
总结
虽然 socket.write()
本身不支持直接指定 remoteAddress
和 port
,但你可以通过创建一个新的套接字连接来实现这一功能。在连接成功后,你可以使用 socket.write()
发送数据到指定的远程地址和端口。
mysql.query(‘SELECT ipAddressCurrent,remotePortCurrent FROM Device WHERE uniqueID = "’+uid+’"’, function(err, fields) { var res = fields[0]; var clientip = res[‘ipAddressCurrent’]; var clientport = res[‘remotePortCurrent’]; c.write(“test”); });
由于 客户的 ip 和 port 已经 存在数据,发送数据给客户时,想直接用 node net 的模块 发送 socket.write(ipaddress:port,“data”); 查了很多资料未找到,socket.io,可以设置客户端标示,可以发指定的客户(相当于聊天室的私聊),但我想看net可否实现。
var io = require('socket.io').listen(888);
//用于记录所有的客户端
var user_coll = {};
io.sockets.on('connection', function (socket) {
//客户端连接成功则设置客户端标示
socket.on('set nickname', function (name) {
user_coll[name] = socket;
user_coll[name].set('username', name, function () { user_coll[name].emit('ready'); });
user_coll[name].on('publicmsg',function(data){
user_coll[name].get('username',function(err, name){
var msg ="public msg - "+ name + " say : "+data;
io.sockets.emit('usermsg',msg);
});
})
user_coll[name].on('privatemsg',function(data){
//console.log(JSON);return false;
var jsonData = eval(data);
user_coll[jsonData.sendTo].get('username',function(err,name){
var msg ="private msg - "+name +" say : "+jsonData.text;
user_coll[jsonData.sendTo].emit('usermsg',msg);
});
});
});
});
此socket非彼socket io.sockets.on(‘connection’, function (socket) { 此处的socket ≠ net模块的socket,两者一毛钱关系都没有。。。 要实现楼主所说的效果,要么放弃socket.io自己在socket协议层上做client和server,要么hack进socket.io的代码,同时修改socket.io的server端和client端的代码,以增加相关api。
socket ≠ net模块 我知道,我想用net,实际没有办法再用socket.io,代码是用一个聊天室的。他用socket.io.
是否可以考虑对每个客户端的连接进行标识,标识存在数据库里,要发送到某个客户端时,调用数据库的标识,socket.write(“data”) 给这个客户端。
API for no namespace:
var clients = io.sockets.clients();
var clients = io.sockets.clients('room'); // all users from room `room`
For a namespace
var clients = io.of('/chat').clients();
var clients = io.of('/chat').clients('room'); // all users from room `room`
=========================================================
io.sockets.on('connection',function(socket){
io.sockets.sockets['nickname'] = socket.id;
client.on("chat", function(data) {
var sock_id = io.sockets.sockets['nickname']
io.sockets.sockets[sock_id].emit("private", "message");
}); });
socket.io 有相关的方法。但我想用 node net 模块 。
客户端是浏览器socket.io,服务端想用socket直接发送数据,这样? 但是。。。socket.io本质上是http长连接,socket是tcp协议。除非hack进socket.io的代码,获取本次http连接底层的socket对象,否则根本就没办法进行tcp层面的通讯。经过千难万苦,获得此socket对象,socket.write(‘hello’)发送数据给客户端,客户端根本无法解析:大哥,你说的哪国语言?请你用socket.io协议说话。最终,还是要用socket.io那套玩意,这不是瞎折腾吗。。。
假设能用net模块,那么下一步必须考虑如何用socket.io协议封装数据(具体socket.io协议实现参考rfc 6455),嗯,慢慢折腾吧。谁让客户端已经定死是socket.io呢。
message->http server(http.js)->tcp server(server.js)->gps client,问题是卡在最后一步, 如何将msg发送给某个gps client,即某个特定remote address &port的连接, 这样?(真心希望能将问题表述的更明确些,猜来猜去真伤脑细胞) 既然能指定客户端的ip&port,那么 server.js至少持有客户端socket对象的引用吧?因此server.js同时接受来自http.js和gps的连接,server.js是router角色?(给出的信息量太少,偶只能猜猜猜。。。)
假使上诉猜测正确,server.js的粗略实现大概如此
var net=require('net');
var user_coll=[];
net.createServer(function(socket){
/** 此处未考虑所谓的拼包,chunk可能不是一个完整的message**/
socket.on('data',function(chunk){
var msg=chunk.toString();
//parse message to find out which type of client?
var info=parse(msg);
if(info.from=='http.js'){ //come from http.js
var username=info.sendTo;
//query db by username, fetch ip&port?
var userInfo=queryUserInfo(username);
for(var i=0;i<user_coll.length;i++){
if(userInfo.remoteAddress==user_coll[i].remoteAddress
&& userInfo.remotePort==user_coll[i].remotePort){
user_coll[i].write('forwarded message');
}
}
}else{ //come from gps client
if(~user_coll.indexOf(socket)){
user_coll.append(socket);
}
//do more work....
}
});
function dispose(){
var index=user_coll.indexOf(socket);
if(~index){
console.log('%s disconneted',socket.remoteAddress);
user_coll.splice(index,1);
socket.removeAllListeners();
}
}
socket.on('end',dispose);
socket.on('close',dispose);
}).listen(8080);
(聊天数据格式未给出,下半部分编不下去了) 另外就楼主最初问题-能不能socket.write(ipaddress:port,“data”),偶的回答是:NO。node不存在类似的api,当然也能写个类似的方法
function socket_write(ipaddress,port,"data"){
var socket=net.conenct(port,ipaddress);
socket.write("data");
}
不过这应该不是楼主的本意吧。
server.js 同时连接gps client和http.js 问题就是要用浏览器发指令给gps client,你的答案应该可以解决问题,衷心感谢。
少了这句:
user_coll.push(socket);
成功根据客户的ID发送数据到客户端,感谢帮助。
在 Node.js 中,socket.write()
方法用于向已连接的套接字写入数据。socket.write()
并不直接支持指定 remoteAddress
和 remotePort
,因为该方法默认就是将数据发送到已经建立连接的对端。
为了实现向特定的远程地址和端口发送数据,你需要创建一个新的套接字连接,并在连接成功后使用 socket.write()
方法发送数据。以下是一个示例代码来说明这一过程:
const net = require('net');
// 定义目标地址和端口
const remoteAddress = '127.0.0.1';
const remotePort = 8080;
// 创建一个新的 TCP 套接字
const clientSocket = new net.Socket();
// 当套接字连接成功时触发
clientSocket.connect(remotePort, remoteAddress, () => {
console.log(`Connected to ${remoteAddress}:${remotePort}`);
// 向连接的目标地址和端口发送数据
const dataToSend = "Hello, world!";
clientSocket.write(dataToSend);
});
// 监听错误事件
clientSocket.on('error', (err) => {
console.error('Socket error:', err);
});
// 监听关闭事件
clientSocket.on('close', () => {
console.log('Connection closed');
});
在这个例子中,我们首先定义了目标地址 (remoteAddress
) 和端口 (remotePort
)。然后,我们创建了一个新的 TCP 套接字 (clientSocket
) 并调用 connect()
方法来连接到指定的远程地址和端口。一旦连接成功,我们就可以使用 socket.write()
方法来发送数据。
请注意,在实际应用中,你需要根据实际情况来处理连接失败、错误和其他边缘情况。