madsci1016
Member
Title says it all. Current Arduino API will not return a socket (wrapped in a Ethernet Client class) unless it's received data on that socket. I'm trying to implement an FTP server with passive mode on a Teensy 3.5. The passive data socket will never receive data from the FTP client, only send. Further, the client will hang if the data socket is not closed by the server.
So first attempts at just using server.write do send the data, but since I have no way to close the socket, the FTP client hangs.
The base Arduino Ethernet library does make EthernetClient::status() and EthernetClass::_server_port public members. So I believe I could iterate through all sockets in userspace and find my open server socket to solve this problem. However the teensy version EthernetClass::socketStatus() is private and EthernetServer::server_port is commented that it will become private soon. So I can't iterate through sockets in userspace to find my established server connection.
For now, I may try to just use server.writes and the public EthernetServer::server_port to iterate through and close all connections that match the server port.
Open to other suggestions as well.
(Looks at code again...)
OK, EthernetClient::status() provides public access to EthernetClass::socketStatus(). So i was able to get this implemented using non-documented API calls.
So this is working for me, i iterate through all the sockets till i find one that matches my saved port number and shows as TCP established in status. But since this is undocumented API the Teensy Ethernet library does not match the Arduino Ethernet library (where the port numbers are saved) so this isn't portable. Would be nice if we could establish a documented call to retrieve connected clients that haven't sent data.
Ok, now on to figure out why every TCP packet is taking 200ms to ACK and severely slowing down the file transfer....
So first attempts at just using server.write do send the data, but since I have no way to close the socket, the FTP client hangs.
The base Arduino Ethernet library does make EthernetClient::status() and EthernetClass::_server_port public members. So I believe I could iterate through all sockets in userspace and find my open server socket to solve this problem. However the teensy version EthernetClass::socketStatus() is private and EthernetServer::server_port is commented that it will become private soon. So I can't iterate through sockets in userspace to find my established server connection.
For now, I may try to just use server.writes and the public EthernetServer::server_port to iterate through and close all connections that match the server port.
Open to other suggestions as well.
(Looks at code again...)
OK, EthernetClient::status() provides public access to EthernetClass::socketStatus(). So i was able to get this implemented using non-documented API calls.
Code:
for (int sock = 0; sock < MAX_SOCK_NUM; sock++) {
EthernetClient data(sock);
if (dataServer.server_port[sock] == FTP_DATA_PORT_PASV) {
uint8_t s = data.status();
if (s == 0x17 || s == 0x1C) {
//assume its the first established one we find with the server port number
//data = myclient;
pasvDataSocket = sock;
return true;
}
}
}
So this is working for me, i iterate through all the sockets till i find one that matches my saved port number and shows as TCP established in status. But since this is undocumented API the Teensy Ethernet library does not match the Arduino Ethernet library (where the port numbers are saved) so this isn't portable. Would be nice if we could establish a documented call to retrieve connected clients that haven't sent data.
Ok, now on to figure out why every TCP packet is taking 200ms to ACK and severely slowing down the file transfer....