Node.js tcp 连接

米克兹

解决承诺后如何发送“结束”消息?有时我可以发送 4 条中的 2 条“结束”消息,有时是 3 条。正在下载来自 FTP 的文件,这没问题。唯一不起作用的是在下载文件后发送“结束”消息。你知道为什么这段代码不能正常工作吗?

此代码已更新:

const ftp = require("jsftp");
const fs = require("fs");
const net = require("net");
const mkdirp = require("mkdirp");

class ftpCredentials {
  constructor(host) {
    this.user = "xxx";
    this.pass = "xxx";
    this.host = host;
  }
}

const downloadFromFTP = (credentials, file) => {
  const client = new ftpCredentials(credentials.host);
  const ftpClient = new ftp(client);
  return new Promise((res, rej) => {
    let buf = null;
    ftpClient.get(file, (err, stream) => {
      if (!err && typeof stream !== "undefined") {
        // Events
        stream.on("data", (data) => {
          if (buf === null) buf = new Buffer(data);
          else buf = Buffer.concat([buf, data]);
        });
        stream.on("close", (err) => {
          if (err) rej("FILE_ERROR");
          const actualPath = `${credentials.path}/${file}`;
          fs.writeFile(actualPath, buf, "binary", (err) => {
            if (err) rej(err);
            ftpClient.raw("quit", (err, data) => {
              if (err) rej(err)
              res(file);
            });
          });
        });
        // Resume stream
        stream.resume();
      } else {
        rej("STREAM_ERROR");
      }
    });
  })
}

const handleSavingFile = (credentials, filesOnFTP) => {
  mkdirp(credentials.path, () => {
    fs.readdir(credentials.path, (err, fileNames) => {
      if (err) return err;
      const needToConnectToFTP = filesOnFTP.filter(name => fileNames.indexOf(name) !== -1).length === 0;
      const socketForEndMsg = net.createConnection(18005, credentials.host, () => {
        Promise.all(filesOnFTP.map((file) => {
          return new Promise((resolve, reject) => {
            // The problem is here:
            const socketWrite = socketForEndMsg.write(`End|ftp://${credentials.host}/${file}`, "UTF16LE");
            resolve(socketWrite);
            // Events
            socketForEndMsg.on("error", () => {
              console.log("Problem with sending End message!");
              reject();
            });
          });
        })).then(() => {
          socketForEndMsg.end();
        }).catch((err) => {
          console.log(err);
        });
      });
    })
  })
}


const getScheme = (credentials) => {
  const socketForData = net.createConnection(18005, credentials.host, () => socketForData.write("Scheme", "UTF16LE"));
  // Events
  socketForData.on("close", () => console.log("TCP Connection closed"));
  socketForData.on("error", err => console.log(err));
  socketForData.on("data", (data) => {
    socketForData.end();

    const toUTF16Format = Buffer.from(data).toString("UTF16LE");
    const arrayFromTCPMessage = toUTF16Format.split(/\||;/);
    const filteredImages = arrayFromTCPMessage.filter(item => item.startsWith("scheme"))
    const isOK = arrayFromTCPMessage[0] === "OK";

    if (isOK) {
      handleSavingFile(credentials, filteredImages);
    }
  })
}

module.exports = getScheme;

Error message: Error: This socket is closed
at Socket._writeGeneric (net.js:722:18)
at Socket._write (net.js:782:8)
at doWrite (_stream_writable.js:407:12)
at writeOrBuffer (_stream_writable.js:393:5)
at Socket.Writable.write (_stream_writable.js:290:11)
at Promise (xxx\getScheme.js:56:29)
at new Promise (<anonymous>)
at Promise.all.filesOnFTP.map (xxx\getScheme.js:54:18)
at Array.map (<anonymous>)
at Socket.net.createConnection (xxx\getScheme.js:52:32)
探险家

我明白了,你喜欢听error事件,这让你Promise用来捕捉错误。但是,error事件处理程序注册的位置是错误的,因为它在.map函数调用内部因此,error事件将被注册filesOnFTP长度的次数

我已将该错误处理程序移至下一行并使用writable标志查看套接字在写入之前是否仍可写。我还添加了更多事件处理程序,它们将为您提供有关套接字状态的更多信息(用于调试,您可以稍后删除它们)。

const handleSavingFile = (credentials, filesOnFTP) => {
  mkdirp(credentials.path, () => {
    fs.readdir(credentials.path, (err, fileNames) => {
      if (err) return err;
      const needToConnectToFTP = filesOnFTP.filter(name => fileNames.indexOf(name) !== -1).length === 0;
      const socketForEndMsg = net.createConnection(18005, credentials.host, () => {
        for(let file of filesOnFTP) {
            // Before write to socket, check if it is writable still! 
            if(socketForEndMsg.writable) {
                socketForEndMsg.write(`End|ftp://${credentials.host}/${file}`, "UTF16LE");
            }
            else {
                console.log('Socket is not writable! May be closed already?');
            }
        }
      });

      // This is the correct place for the error handler!
      socketForEndMsg.on("error", (error) => {
        console.log("Problem with sending End message!", error);
      });

      socketForEndMsg.on("close", () => {
        console.log("Socket is fully closed!");
      });

      socketForEndMsg.on("end", () => {
        console.log("The other end of the socket has sent FIN packet!");
      });

    });

  });

}

让我知道这个是否奏效!

谢谢!

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章