这完全取决于您的协议设计。
套接字旨在模拟串行接口的工作方式 - 数据一次输入 8 位,并且……仅此而已。套接字没有消息的概念——只有字节。将插座视为 USB 键盘。当用户一次键入一个字母时,您的软件只能获取字节(有时,如果用户键入速度足够快或按住某个键,您的软件会获取字节组)。您需要决定是什么构成了“数据包”。一句话?然后你的软件应该会检测到句号"."。一条线?然后你检测换行符。
以下是 HTTP 1.0 客户端的简单示例(主要区别在于 HTTP 1.0 通过关闭连接来表示数据包结束,而 HTTP 1.1 发送 Content-Length 标头):
function HTTP_1_0_client (url) {
let urlParts = url.match(/http:..([^/]+)(.*)/);
let domain = urlParts[1];
let path = urlParts[2];
return new Promise((resolve, reject) => {
let rawString = '';
const client = net.createConnection(80, domain);
client.write('GET ' + path + ' HTTP/1.0\n\n');
client.on('data', buf => rawString += buf.toString());
client.on('end', () => {
// headers and body are separated by two newlines:
let httpParts = rawString.match(/^(.+)\r?\n\r?\n(.*)/);
let headers = httpParts[1].split(/\r?\n/);
let text = httpParts[2];
// first line of response is the status line:
let statusLine = headers.shift();
let status = statusLine.match(/^[0-9]+/)[0];
// return the response to the promise:
resolve({
status: status,
headers: headers,
responseText: text
});
});
client.on('error', err => reject(err));
});
}
在上面的协议中,我们简单地使用套接字连接作为数据包的结束——因此是响应的结束。您可以使用其他条件来检测响应周期的结束并返回响应。这完全取决于协议设计。
下面是另一个简单的协议,它简单地使用 JSON 格式来定义一个数据包:
function JSONclient (host, port, requestData) {
return new Promise((resolve, reject) => {
let rawString = '';
const client = net.createConnection(port, host);
client.write(JSON.stringify(requestData));
client.on('data', buf => {
rawString += buf.toString();
try {
let response = JSON.parse(rawString);
// If we get here it means no errors
// which means packet is complete -
// return response to promise:
resolve(response);
client.destroy(); // close connection
}
catch (err) {
// Ignore parse error
// It just means packet isn't complete yet.
}
});
client.on('error', err => reject(err));
});
}