For reference the link to "Find remote IP TCP" and TisteAndii's post:
Modified the two files that "TisteAndii" outlined in his POST. Compiling the Adafruit_CC3000; HTTPServer.ino example results in 1 error:
F:\Documents_8.1\Arduino_old\libraries\Adafruit_CC3000\Adafruit_CC3000_Server.cpp: In member function 'bool Adafruit_CC3000_Server::acceptNewConnections()':
F:\Documents_8.1\Arduino_old\libraries\Adafruit_CC3000\Adafruit_CC3000_Server.cpp:286:31: error: 'class Adafruit_CC3000_Client' has no member named 'ip_addr'
memcpy(_clients*.ip_addr, &(tSocketClientAddr.sa_data[2]), 4);*
Looks like you botched the first step:
Navigate to the class Adafruit_CC3000_Client in the file Adafruit_CC3000.h. In the class definition, just before the private methods and attributes are defined, you will add a new public attribute as follows:
uint8_t ip_addr[4]; // assuming a typical IPv4 address
@ aarg thank you; appreciate your work!
Modified three files to successfully compile "HTTPServer.ino" example. Three modified files are
attached. Opened "Serial Monitor; greeted with all incorrect "Client IP's."
Client IP's are wrong; all Client IP's should have been 10.0.0.146, computer ip being used to bring up
web page. Attached file is capture of "serial Monitor."
Requesting help with solution to getting Correct Client IP addresses.
William
Client IP's incorrect.txt (1.47 KB)
An IP address is not composed of 5 parts. It is either 4 or 6. The Arduino only supports (I think) 4 parts.
So, you are printing something incorrectly. I suspect that you are also storing data incorrectly, but I can't see your current code.
@ PaulS --Snipet of code that prints client IP:
void loop(void)
{
// Try to get a client which is connected.
Adafruit_CC3000_ClientRef client = httpServer.available();
if (client) {
Serial.println(F("Client connected."));
delay(1000);
Serial.print("Client IP: ");
for (int i = 0; i < 3; i++){
Serial.print(client.ip_addr[i]);
Serial.print('.');
}
Serial.println(client.ip_addr[3]);
@ aargg
I understand "TisteAndii's" POST is not tested. I came hoping to learn and find a solution from the Arduino Team. Thank you for your input and the time spent replying.
Found Texas Instruments POST on this subject:
POST looks like finding of the client ip is doable.
William
That snippet of code did not produce the output you showed us. You need to post ALL of your code INCLUDING any modified libraries.
@PaulS
Attaching three files: 1st modified Adafruit CC3000 Library, 2nd is pdf of My POST on "Arduino Stack Exchange" with "TisteAndii's" latest edits. Third file is the modified "HTTPServer.ino," renamed "FindClientIP.ino."
Sketch I have been working with is the HTTPServer.ino example; modified to print remote ip.
File "Serial Monitor Capture 2.txt" shows the current state of results from these modifications.
William
Adafruit_CC3000--Modified Library.zip (250 KB)
programming - Find remote ip address TCP - Arduino Stack Exchange.pdf (184 KB)
FindClientIP.ino (10.3 KB)
"TisteAndii" and I have been trying to get this to work consistently; however, at best it only works ~50% of the time. When it does not work it only returns "0.0.0.0" and working correctly it returns the client IP address of my host computer "10.0.0.146." These two results are from refreshing the Chrome Browser to open the Server page.
Last code "TisteAndii" presented:
This function is not built-in so you'll have to modify the library slightly. This is one way to do it, I think:
Navigate to the class Adafruit_CC3000_ClientRef in the file Adafruit_CC3000_Server.h. In the class definition, just before the private methods and attributes are defined, you will add a new public attribute as follows:
uint8_t ip_addr[4]; // assuming a typical IPv4 address
It will hold the IP address of each ClientRef instance as the connection is accepted.
Go to Adafruit_CC3000_Server::acceptNewConnections() near the end of Adafruit_CC3000_Server.cpp. A few lines will be added to get the IP address from the CC3000 and store it temporarily in the appropriate struct:
static sockaddr tSocketClientAddr; // file scope
static socklen_t addr_len;
// Accept new connections and update the connected clients.
bool Adafruit_CC3000_Server::acceptNewConnections() {
bool newClientCreated = false;
// For any unconnected client, see if new connections are pending and accept
// them as a new client.
for (int i = 0; i < MAX_SERVER_CLIENTS; ++i) {
if (!_clients[i].connected()) {
// Note: Because the non-blocking option was set for the listening
// socket this call will not block and instead return SOC_IN_PROGRESS (-2)
// if there are no pending client connections. Also, the address of the
// connected client is not needed, so those parameters are set to NULL.
cc3k_int_poll();
addr_len = sizeof(tSocketClientAddr);
int soc = accept(_listenSocket, &tSocketClientAddr, &addr_len);
if (soc > -1) {
_clients[i] = Adafruit_CC3000_Client(soc);
newClientCreated = true;
}
// else either there were no sockets to accept or an error occured.
}
}
return newClientCreated;
}
You'll also edit the getClientRef() method in Adafruit_CC3000_Server.cpp:
Adafruit_CC3000_ClientRef Adafruit_CC3000_Server::getClientRef(int8_t clientIndex) {
if (clientIndex != -1) {
Adafruit_CC3000_ClientRef newClient = Adafruit_CC3000_ClientRef(&_clients[clientIndex]);
// at least 2 (family) + 2 (port) + 4 (ip_addr) bytes expected
// also check if address is standard ipv4
if ((addr_len >= 8) && (tSocketClientAddr.sa_family == AF_INET)){
// copy address into array; in network byte order
memcpy(newClient.ip_addr, &(tSocketClientAddr.sa_data[2]), 4);
}
return newClient;
}
// Couldn't find a client ready to read, so return a client that is not
// connected to signal no clients are available for reading (convention
// used by the Ethernet library).
return Adafruit_CC3000_ClientRef(NULL);
}
Save all the files.
Now the address is stored in an array for each client and can be accessed from your sketch. For example, you can access the address in your sketch like this:
In the loop() of the the HttpServer example:
Adafruit_CC3000_ClientRef client = httpServer.available();
if (client) {
Serial.println(F("Client connected."));
for (int i = 0; i < 3; i++){
Serial.print(client.ip_addr[i]);
Serial.print('.');
}
Serial.println(client.ip_addr[3]);
// other code
}
Any suggestion/s on programming changes.
Best Regards,
William