How to upload multiple files to ftp in one session in Arduino C++ - ftp-client

My code works well to upload first file in the loop to ftp. But it hangs once second file is going to be uploaded.
I'm reading the SD card root folder using lib
first I set the ftp connection using connectFTP() to establish also data transfer port. Next I'm calling the fileTransfer(); While loop function works well, until first file is transfered.
Once second file meet If criteria
if (fileTemp != fileName && fileTemp[0] == '1' && fileTemp[1] == '9')
and send the
client.print(F("STOR "));
client.println(fileTemp);
There is no responce.
Serial.println("\nStarting connection to server...");
// if you get a connection, report back via serial:
if (client.connect(config.server, config.ftpport)) {
Serial.println("connected to server");
}
if(!eRcv()) Serial.println("fail");
client.print(F("USER "));
client.println(config.ftplogin);
if(!eRcv()) Serial.println("fail USER");
client.print("PASS ");
client.println(config.ftppass);
if(!eRcv()) Serial.println("fail PASS");
client.println(F("SYST"));
if(!eRcv()) Serial.println("fail SYST");;
client.println(F("Type I"));
if(!eRcv()) Serial.println("fail TYPE I");
client.println(F("PASV"));
if(!eRcv()) Serial.println("fail PASV");
char *tStr = strtok(outBuf,"(,");
int array_pasv[6];
for ( int i = 0; i < 6; i++) {
tStr = strtok(NULL,"(,");
array_pasv[i] = atoi(tStr);
if(tStr == NULL)
{
Serial.println(F("Bad PASV Answer"));
}
}
unsigned int hiPort,loPort;
hiPort = array_pasv[4] << 8;
loPort = array_pasv[5] & 255;
Serial.print(F("Data port: "));
hiPort = hiPort | loPort;
Serial.println(hiPort);
if (dclient.connect(config.server,hiPort)) {
Serial.println(F("Data connected"));
}
else {
Serial.println(F("Data connection failed"));
client.stop();
}
client.println(F("CWD tpv.cba.pl"));
if(!eRcv()) Serial.println("fail CWD");
delay(500);
}
void fileTransfer() {
if (!root.open("/")) {
sd.errorHalt("open root failed");
}
char fileTemp[13];
while (ftpfile.openNext(&root, O_RDONLY)) {
ftpfile.getName(fileTemp,13);
//Serial.println(fileTemp);
if (fileTemp != fileName && fileTemp[0] == '1' && fileTemp[1] == '9') {
Serial.println(fileTemp);
client.print(F("STOR "));
client.println(fileTemp);
if(!eRcv()) Serial.println("fail STOR");
size_t m;
while((m = ftpfile.read(fileBuf, sizeof(fileBuf)))>0) {
dclient.write(fileBuf, m);
}
if(!eRcv()) Serial.println("fail STOR");
}
ftpfile.close();
}
dclient.stop();
Serial.println(F("Data disconnected"));
if(!eRcv()) Serial.println("fail Data disconnet");
client.println(F("QUIT"));
if(!eRcv()) Serial.println("fail QUIT");
client.stop();
Serial.println(F("Command disconnected"));
}
Logs received:
Starting connection to server...
connected to server
220---------- Welcome to Pure-FTPd [privsep] [TLS] ----------
220-You are user number 49 of 300 allowed.
220-Local time is now 14:11. Server port: 21.
220-This is a private system - No anonymous login
220-IPv6 connections are also welcome on this serve331 User xxxxx OK. Password required
230-Your bandwidth usage is restricted
230-OK. Current restricted directory is /
230 Max allowed filesize is 10485760 bytes
215 UNIX Type: L8
200 TYPE is now 8-bit binary
227 Entering Passive Mode (81,171,31,230,225,201)
Data port: 57801
Data connected
250 OK. Current directory is /xxx.cba.pl
19080400.log
150 Accepted data connection
226-File successfully transferred
226 0.094 seconds (measured here), 59.55 Kbytes per second
19080402.log

I moved the PASV part from connectFTP() to fileTransfer() and it helps for loop, but still only max 6KB of file is stored at ftp.
void fileTransfer() {
if (!root.open("/")) {
sd.errorHalt("open root failed");
}
char fileTemp[13];
while (ftpfile.openNext(&root, O_RDONLY)) {
ftpfile.getName(fileTemp,13);
//Serial.println(fileTemp);
if (fileTemp != fileName && fileTemp[0] == '1' && fileTemp[1] == '9') {
client.println(F("PASV"));
if(!eRcv()) Serial.println("fail PASV");
char *tStr = strtok(outBuf,"(,");
int array_pasv[6];
for ( int i = 0; i < 6; i++) {
tStr = strtok(NULL,"(,");
array_pasv[i] = atoi(tStr);
if(tStr == NULL) Serial.println(F("Bad PASV Answer"));
}
unsigned int hiPort,loPort;
hiPort = array_pasv[4] << 8;
loPort = array_pasv[5] & 255;
Serial.print(F("Data port: "));
hiPort = hiPort | loPort;
Serial.println(hiPort);
if (dclient.connect(config.server,hiPort)) {
Serial.println(F("Data connected"));
} else {
Serial.println(F("Data connection failed"));
client.stop();
}
Serial.print(F("TEST: "));
Serial.println(fileTemp);
client.print(F("STOR "));
client.println(fileTemp);
delay(100);
if(!eRcv()) Serial.println("fail STOR");
for (uint32_t i=0; i< ftpfile.fileSize(); i += sizeof(fileBuf)){
//Serial.println(i);
ftpfile.read(fileBuf,sizeof(fileBuf));
dclient.write(fileBuf, sizeof(fileBuf));
}
if(!eRcv()) Serial.println("fail STOR");
dclient.stop();
Serial.println(F("Data disconnected"));
//if(!eRcv()) Serial.println("fail Data disconnet");
}
ftpfile.close();
}
client.println(F("QUIT"));
if(!eRcv()) Serial.println("fail QUIT");
client.stop();
Serial.println(F("Command disconnected"));
}
Logs received this time:
230-OK. Current restricted directory is /
230 Max allowed filesize is 10485760 bytes
215 UNIX Type: L8
200 TYPE is now 8-bit binary
227 Entering Passive Mode (81,171,31,230,202,243)
Data port: 51955
Data connected
TEST: 19080400.log
150 Accepted data connection
226-File successfully transferred
226 0.081 seconds (measured here), 68.95 Kbytes per second
Data disconnected
227 Entering Passive Mode (81,171,31,230,200,207)
Data port: 51407
Data connected
TEST: 19080402.log
150 Accepted data connection
226-File successfully transferred
226 0.085 seconds (measured here), 66.11 Kbytes per second
Data disconnected
227 Entering Passive Mode (81,171,31,230,203,91)
Data port: 52059
Data connected
TEST: 19080404.log
150 Accepted data connection
226-File successfully transferred
226 0.084 seconds (measured here), 67.00 Kbytes per second
Data disconnected
227 Entering Passive Mode (81,171,31,230,228,193)
Data port: 58561
Data connected
TEST: 19080504.log
150 Accepted data connection
226-File successfully transferred
226 0.079 seconds (measured here), 70.81 Kbytes per second
Data disconnected
227 Entering Passive Mode (81,171,31,230,214,248)
Data port: 55032
Data connected
TEST: 19080506.log
150 Accepted data connection
19080506.log is about 4KB and program hangs up

Related

NodeJs tcp socket receive chunk

const net = require('net')
const sockets = []
server.on('connection', sock => {
log("tcp_server", "info", `Connected at ${sock.remoteAddress}:${sock.remotePort}`)
sockets.push(sock);
// Write the data back to all the connected, the client will receive it as data from the server
sockets.forEach((sock, index, array) => {
})
sock.on('data', data => {
})
// Add a 'close' event handler to this instance of socket
sock.on('close', data => {
}) // end sock.on
})
server.listen(conf.port, conf.serverHost, () => {
const address = server.address()
const port = address.port
const family = address.family
const ipaddr = address.address
log("tcp_server", "info", 'Server is listening at port ' + port)
log("tcp_server", "info", 'Server ip :' + ipaddr)
log("tcp_server", "info", 'Server is IP4/IP6 : ' + family)
})
this is my socket tcp server
and i faced problem with receive chunk data in c# its easy to receive every chunk if i know the size of it
and i can control how much byte i want to receive every time
now in NodeJs i can get the buffer length by get first 5 byte
and then get the size of the message
var size = (buff[1] << 24) | (buff[2] << 16) | (buff[3] << 8) | buff[4];
i tried this simple code for get the chunk data and process it
first i define a Buffer in top
var mybuffer = Buffer.alloc(30);
var length = 0;
sock.on('data', data => {
data.copy(mybuffer, length , 0, data.length); //copy buffer to mybuffer
length += data.length;
//now check if my length is 5 or greater i can determine the buffer size i sent
size = (buff[1] << 24) | (buff[2] << 16) | (buff[3] << 8) | buff[4];
//now need to continue receive until i reach (size - length) = total bytes i sent
})
this what i tried for receive all the chunk but still need more work
any idea how to receive all data depend on size i sent on first 5 bytes of every message
I found this code easysocket! similar to what i want i just made simple edit to the code and its work like charm

Struggling to get ESP8266 on Arduino Uno working reliably with AT communication

I am struggling to get ESP8266 connected to an Arduino Uno working reliably as a webserver. The firmware of my ESP8266 is 1.1.1 - I don't have the option (or knowledge) to update it at the moment. Below is my code. It works, barely, if I serve a small string. However, it usually closes the connection or just loads forever (crashes?) if I try to load the page from the browser three or four times. Ultimately I need to serve a webpage with json embedded in it that will load a second page served by the esp8266, a json file. I have a working demo of that but it crashes after a few retrievals. I understand that my html page is too long for strings so have been attempting to shift across to PROGMEM, initially testing with just a short string. I am storing and retrieving that correctly (I think, at least I can Serial.print it) but as soon as I try to write it to the ESP8266 I get a never ending load in my browser.
Where am I going wrong here? Is it the string/PROGMEM that is causing the issues or is there something else I'm missing in the AT commands (like some sort of ping to keep the connection open)?
//load softserial library
#include <SoftwareSerial.h>
#include <avr/pgmspace.h>
//set a boolean constant variable to true
//#define DEBUG true
const boolean DEBUG = true;
//RX (pin 2) goes to TX on esp8266, TX (pin 3) goes to RX on esp8266
SoftwareSerial esp8266(2, 3);
//input from the photoresistor
//int photoresistorpin = 0;
//create a PROGMEM variable
//String WEBPAGE = "hello";
static const char PROGMEM WEBPAGE[] = {"hello"};
/*
static const char WEBPAGE[] PROGMEM = R"rawliteral(
<html>
<head>
<meta name="viewport" content="width=device-width, minimumscale=1, maximum-scale=1, initial-scale=1">
</head>
<h1>Light:</h1><div id="light"></div>
<script>
function loadDoc()
{
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200)
{
var obj = JSON.parse(this.responseText);
document.getElementById('light').innerHTML = obj.data[0].datavalue;
}
};
xhttp.open('GET', 'data.json', true); xhttp.send();
}
var timedEvent = setInterval(function() { loadDoc(); }, 5000);
</script>
</body>
</html>
)rawliteral";
*/
//const int WEBPAGE_len = sizeof(WEBPAGE)/sizeof(WEBPAGE[0]);
void setup()
{
//open the serial port
Serial.begin(115200);
//print setup started in the serial monitor
Serial.println("Setup started");
//start esp8266 module (note: your esp's baud rate might be different)
esp8266.begin(115200);
//reset esp8266 module
senddata("AT+RST\r\n", 2000, DEBUG);
//set esp8266 as access point mode
//1 = Station mode (client)
//2 = Access point mode (host)
//3 = Access point mode + Station mode
senddata("AT+CWMODE=2\r\n", 1000, DEBUG);
//get ip address for esp8266
senddata("AT+CIFSR\r\n", 2000, DEBUG);
//configure esp8266 for multiple connections
senddata("AT+CIPMUX=1\r\n", 1000, DEBUG);
//turn on esp8266 server on port 80
senddata("AT+CIPSERVER=1,80\r\n", 1000, DEBUG);
//setup completed
Serial.println("Setup done");
}
void loop()
{
//take a reading from the photoresistor
//int lightval = analogRead(photoresistorpin);
int lightval = random(1000);
//to test
//Serial.println(lightval);
//is the esp8266 sending a message
if (esp8266.available())
{
//if received data from esp8266
if (esp8266.find("+IPD,"))
{
//subtract 48 because the read() function returns the ASCII decimal
//value and 0 (the first decimal number) starts at 48
int connectionid = esp8266.read() - 48;
//Serial.println("");
//Serial.println("*****");
//Serial.print("string = ");
//read the url sent by the client, look for the variable (/)
String msg;
esp8266.find("/");
delay(100);
msg = esp8266.readStringUntil(' ');
String pathrequested = msg.substring(0);
Serial.println("*****");
Serial.println(pathrequested);
Serial.println("*****");
//create a senddata string to send the webpage to the esp8266
String cipsend = "AT+CIPSEND=" + String(connectionid) + ",";
//cipsend += WEBPAGE.length();
cipsend += strlen_P(WEBPAGE);
cipsend += "\r\n";
Serial.println(cipsend);
char buffer[1000];
strcpy_P(buffer, WEBPAGE);
Serial.println(buffer);
//senddata(cipsend, 500, DEBUG);
//senddata(WEBPAGE, 500, DEBUG);
senddata(buffer, 500, DEBUG);
//create a string closecommand with the connection id and send it
String closecommand = "AT+CIPCLOSE=" + String(connectionid) + "\r\n";
senddata(closecommand, 500, DEBUG);
//increment the count
//count++;
}
}
}
void senddata(String command, const int timeout, boolean debug)
{
//send the received command to the esp8266
esp8266.print(command);
//set int variable to the number of millisends since Arduino began
long int time = millis();
//while the time and the timeout is less than the number of millisends since Arduino began
while((time + timeout) > millis())
{
//while the esp8266 is sending messages
while(esp8266.available())
{
//display output in the serial window
Serial.write(esp8266.read());
}
}
}
Assuming that "get a never ending load in my browser" means no display in the browser - check the following:
1. Get rid of String amd String constructors (+=) in your code and replace it with a fixed char array for the building of messages. Read more: https://hackingmajenkoblog.wordpress.com/2016/02/04/the-evils-of-arduino-strings/
2. My experience with the AT interface was - more than 9600 baud is not reliable and this is not sufficient for doing what you want.
3. If your Esp module has min 512kb (most likely up to 4Mb) host your code there and use the UNO only as sigmal receiver/sender from the attached hardware/ sensors. Save yourself a lot of trouble and problems - most of the examples with AT com are not really working and more of a pain in the ***. I ditched the AT interface within 2 days and never in the last 4 years missed anything. By flashing code to the Esp module you also have full control and visibility on whats going on due to the debug possiblitie AND you can even host html/css/js on the File system there (LittleFS / SPIFFS)

Best practice for seperating Node TCP stream into packets?

I'm using Node's TCP client for a real-time backend for my game, which communicates in a fixed-length protocol. For example,
0x00 - Connection Request
int32 Identifier
4 bytes long
0x01 - Position Update
int32 positionx
int32 positiony
8 bytes long
Of course, Node works like this
socket.on("data", (data) => {
// Arbitary buffer of bytes
})
I only want to process packets one at a time once they've been recieved in full, but what's the best way to A: continue adding to a buffer until the full packet is recieved and B: make sure not to include the data of a second packet in the first one
This is how I solved it!
function readData(data, socket) {
console.log("Read chunk of data " + data.length + " bytes long")
while (data.length > 0) {
if (expectsNewPacket) {
packetBuffer = new Buffer(0)
currentPacketInfo = getPacketInformationFromHeader(data)
data = currentPacketInfo.slicedData
console.log("New packet: ident " + currentPacketInfo.ident + ", length: " + currentPacketInfo.length)
expectedLengthRemaining = currentPacketInfo.length
expectsNewPacket = false
}
// If the data is more than the rest of the packet, just concat the rest of the packet and remove it from our block
if (data.length >= expectedLengthRemaining) {
packetBuffer = Buffer.concat([packetBuffer, data.slice(0, expectedLengthRemaining)])
data = data.slice(expectedLengthRemaining)
processPacket(packetBuffer, socket)
expectsNewPacket = true
} else {
// Or if the data length is less than what we need, just add all that we can and we'll add more later
packetBuffer = Buffer.concat([packetBuffer, data.slice(0, data.length)])
data = data.slice(data.length)
}
}
}

How to calculate node.js socket buffer to avoid allocating memory and never using it?

I'm using node.js as a server between pairs of clients, to handle my online game.
Clients send short messages between hem [one message should not exceed 200bytes].
Currently I expect single client to send [on average] 1 message per second [keeping in mind it can be 5 seconds of nothing and 5 messages one after another].
I've downloaded a sample server using 'net' module and rewritten it to handle the messages the way I need them to be handled.
Basically, for every connected socket, it creates a Buffer with size of 1024*8.
Currently I'm testing my game with some bots, which simply connect, wait 3 seconds and disconnect. They only send 1 message. Nothing else happening.
function sendMessage(socket, message) {
socket.write(message);
}
server.on('connection', function(socket) {
socket.setNoDelay(true);
socket.connection_id = require('crypto').createHash('sha1').update( 'krystian' + Date.now() + Math.random() ).digest('hex') ; // unique sha1 hash generation
socket.channel = '';
socket.matchInProgress = false
socket.resultAnnounced = false;
socket.buffer = new Buffer(cfg.buffer_size);
socket.buffer.len = 0; // due to Buffer's nature we have to keep track of buffer contents ourself
_log('New client: ' + socket.remoteAddress +':'+ socket.remotePort);
socket.on('data', function(data_raw) { // data_raw is an instance of Buffer as well
if (data_raw.length > (cfg.buffer_size - socket.buffer.len)) {
_log("Message doesn't fit the buffer. Adjust the buffer size in configuration");
socket.buffer.len = 0; // trimming buffer
return false;
}
socket.buffer.len += data_raw.copy(socket.buffer, socket.buffer.len); // keeping track of how much data we have in buffer
var str, start, end
, conn_id = socket.connection_id;
str = socket.buffer.slice(0,socket.buffer.len).toString();
if ( (start = str.indexOf("<somthing>")) != -1 && (end = str.indexOf("</something>")) != -1) {
try {
if (!<some check to see if the message format is right>) {
sendMessage(socket, "<error message to the client>");
return;
}
<storing info on the socket>
} catch(err) {
sendMessage(socket, "<error message to the client>");
return;
}
socket.channel = <channel>;
str = str.substr(end + 11);
socket.buffer.len = socket.buffer.write(str, 0);
sockets[socket.channel] = sockets[socket.channel] || {}; // hashmap of sockets subscribed to the same channel
sockets[socket.channel][conn_id] = socket;
waiting[socket.channel] = waiting[socket.channel] || {};
waiting[socket.channel][conn_id] = socket;
sendMessage(socket, "<info message to the client>");
for (var prop in waiting[socket.channel]) {
if (waiting[socket.channel].hasOwnProperty(prop) && waiting[socket.channel][prop].connection_id != socket.connection_id) {
<here I'll try to advertise this client among other clients>
sendMessage(waiting[socket.channel][prop], "<info to other clients about new client>");
}
}
}
var time_to_exit = true;
do{ // this is for a case when several messages arrived in buffer
if ( (start = str.indexOf("<some other format>")) != -1 && (end = str.indexOf("</some other format>")) != -1 ) {
var json = str.substr( start+19, end-(start+19) );
var jsono;
try {
jsono = JSON.parse(json);
} catch(err) {
sendMessage(socket, "<parse error>");
return;
}
if (<message indicates two clients are going to play together>) {
if (waiting[socket.channel][jsono.other_client_id] && waiting[socket.channel][socket.connection_id]) {
delete waiting[socket.channel][jsono.other_client_id];
delete waiting[socket.channel][socket.connection_id];
var opponentSocket = sockets[socket.channel][jsono.other_client_id];
sendMessage(opponentSocket, "<start game with the other socket>");
opponentSocket.opponentConnectionId = socket.connection_id;
sendMessage(socket, "<start game with the other socket>");
socket.opponentConnectionId = jsono.other_client_id;
}
} else if (<check if clients play together>) {
var opponentSocket = sockets[socket.channel][socket.opponentConnectionId];
if (<some generic action between clients, just pass the message>) {
sendMessage(sockets[socket.channel][socket.opponentConnectionId], json);
} else if (<match is over>) {
if (<match still in progress>) {
<send some messages indicating who won, who lost>
} else {
<log an error>
}
delete sockets[socket.channel][opponentSocket.connection_id];
delete sockets[socket.channel][socket.connection_id];
}
}
str = str.substr(end + 20); // cut the message and remove the precedant part of the buffer since it can't be processed
socket.buffer.len = socket.buffer.write(str, 0);
time_to_exit = false;
} else { time_to_exit = true; } // if no json data found in buffer - then it is time to exit this loop
} while ( !time_to_exit );
}); // end of socket.on 'data'
socket.on('close', function(){ // we need to cut out closed socket from array of client socket connections
if (!socket.channel || !sockets[socket.channel]) return;
if (waiting[socket.channel] && waiting[socket.channel][socket.connection_id]) {
delete waiting[socket.channel][socket.connection_id];
}
var opponentSocket = sockets[socket.channel][socket.opponentConnectionId];
if (opponentSocket) {
sendMessage(opponentSocket, "<the other client has disconnected>");
delete sockets[socket.channel][socket.opponentConnectionId];
}
delete sockets[socket.channel][socket.connection_id];
_log(socket.connection_id + " has been disconnected from channel " + socket.channel);
}); // end of socket.on 'close'
}); // end of server.on 'connection'
server.on('listening', function(){ console.log('Listening on ' + server.address().address +':'+ server.address().port); });
server.listen(cfg.port);
I've pasted the above code [very stripped version of the original] to give you and idea about how simple the server is.
I've got an array of sockets, who joined the game and array of sockets on the waiting list, waiting for another client to play with.
Nothing else is going on.
Still the script is memory hungry - 5 hours of connecting and disconnecting gave me this:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
31461 ec2-user 20 0 995m 91m 7188 S 0.7 15.4 1:29.07 node
I think this is way too much.
I'm using nodetime.com free service at the moment to monitor the script, but none of the metrics would suggest the script gained so much memory (it starts with just 10-12MB).
I believe this is due to the buffers, and because they allocate too much memory.
I'm only wondering, if my assumptions regarding buffer size are correct.
Should I adjust the buffer to reflect the amount of data I expect from the client?
If I expect the client to send 5 messages with a very short time between them, 200 bytes max each, should I assume that 1024*3 would be enough?
Or should I adjust buffer size according to the message size I expect, so if I'm sure the message will never go above 300 bytes, I should be fine with buffer size of 512?
Thanks,
Krystian
EDIT:
Node version:
$ node -v
v0.10.5
$ npm -v
1.2.19
EDIT2:
I've tested the script with 400 connections connecting and disconnecting and memory usage dropped significantly to around 60MB. After changing the test setup back to 4 connections it went up again.
The kernel has a socket receive buffer which is at least 8k., which takes care of multiple incoming messages on the socket. You don't need to buffer messages you've already read, so your application buffer doesn't need to be any bigger than the largest expected message.

Can not catch over >1000 message when server send over 1000 message at a time nodejs udp

I write application to send file multicast by nodejs
I read file by chunk and send it in block like this
for (var block = 1; block <= number_of_block; block++) {
sendBlock(FILEPATH, block)
function sendBlock by CHUNK
function sendBlock(file, block) {
fs.open(file, 'r', function(err, fp) {
if (err) {
return;
}
var buf = new Buffer(4 + CHUNK_SIZE);
fs.read(fp, buf, 4, CHUNK_SIZE, (block - 1) * CHUNK_SIZE, function(err, bytesRead) {
if (err) {
}
buf[0] = 0;
buf[1] = opcodes.OPCODE_DATA;
buf[2] = (block >> 8) & 0xFF;
buf[3] = block & 0xFF;
udpserver.send(buf, 0, 4 + bytesRead, PORT, MULTICAST_IP_ADDRESS);
fs.close(fp);
});
});
I create client to receive message
fs.open(fileName, 'a', function(e, id) {
if (4 + CHUNK_SIZE > message.length) {
fs.write(fd, message, 4, message.length - 4, (block - 1) * CHUNK_SIZE, function() {
fs.close(fd, function() {
console.log('file closed', block);
send("miss block:" + missArray);
});
});
} else {
console.log("message length:", message.length)
console.log((block - 1) * CHUNK_SIZE)
fs.write(fd, message, 4, CHUNK_SIZE, (block - 1) * CHUNK_SIZE, function() {
fs.close(fd, function() {
console.log('1file closed', block);
if (block % NUMBER_BLOCK == 0) {
if (blockArray.length > 0) {
missArray = missArray.concat(blockArray);
}
blockArray = range(block + 1, NUMBER_BLOCK)
}
//udpserver.send(block+1)
});
});
}
});
But when server send over 1000 message client can not catch it all
server send
block -- 6907
block -- 6908
block -- 6909
block -- 6910
block -- 6911
block -- 6912
block -- 6913
client reveive and write
block ------ 1008
block ------ 1009
block ------ 1010
block ------ 1011
And I test the maximum file to receive is 10.4 MB.
How to receive all data from sender?
Node.js is subject to the limitations of the underlying operating system. The operating system puts limits on the number of outstanding handles that can be concurrently held by a process.
It's likely that you're exhausting the number of available file descriptors. I recommend using connection pooling to reduce the number of file descriptors that your applications attempt to consume. So instead of trying to send 1000 things at once, limit your program to a pool of say 100 connections at a time.
There are several connection pooling libraries available through npm - one popular choice is poolr.

Resources