I am doing simple proof of concept trying to send C++ program output to Adafruit CC3000 WiFi Shield (using Visual Studio 2013 Desktop Edition on Windows 8.1).
In my design laptop is connected to UNO via USB, UNO is connected to WiFi Shield, and WiFi Shield is connected to D-Link router running Adafruit example sketch ("EchoServer"). These connections are working fine.
Next, I am using TCP client sample code from Microsoft for WiFi connectivity with client code running on the laptop to connect to WiFi Shield. Tested this code with sample TCP server code from Microsoft, and client was able to communicate with server code but for some reason this client is not able to find WiFi Shield TCP Server. I get "Unable to connect to server" error with CC3000 continue to show it is listening for connections but never finds one
I am sure it is due to my lack of understanding TCP/networking world. Below is the client code I am running on laptop using Visual Studio:
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <WinSock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
#include<iostream>
// Need to link with Ws2_32.lib, Mswsock.lib, and Advapi32.lib
#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "Mswsock.lib")
#pragma comment (lib, "AdvApi32.lib")
#define DEFAULT_BUFLEN 512 //Default buffer length of port
#define DEFAULT_PORT "7" //Change this to change port
int main()//int argc, char **argv
{
WSADATA wsaData;
SOCKET ConnectSocket = INVALID_SOCKET;
struct addrinfo *result = NULL,
*ptr = NULL,
hints;
char *sendbuf = "100";
char recvbuf[DEFAULT_BUFLEN];
int iResult;
int recvbuflen = DEFAULT_BUFLEN;
/*
// Validate the parameters - not necessary for use
if (argc != 2) {
printf("usage: %s server-name\n", argv[0]);
system("pause"); return 1;
}
*/
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
system("pause"); return 1;
}
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// Resolve the server address and port
iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
if (iResult != 0) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
system("pause"); return 1;
}
// Attempt to connect to an address until one succeeds
for (ptr = result; ptr != NULL; ptr = ptr->ai_next) {
// Create a SOCKET for connecting to server
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype,
ptr->ai_protocol);
if (ConnectSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
system("pause"); return 1;
}
// Connect to server.
iResult = connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
if (iResult == SOCKET_ERROR)
{
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
continue;
}
break;
}
freeaddrinfo(result);
if (ConnectSocket == INVALID_SOCKET) //If failed to get a socket, end program
{
printf("Unable to connect to server!\n");
WSACleanup();
system("pause"); return 1;
}
// Send an initial buffer
iResult = send(ConnectSocket, sendbuf, (int)strlen(sendbuf), 0);
if (iResult == SOCKET_ERROR) {
printf("send failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
system("pause"); return 1;
}
printf("Bytes Sent: %ld\n", iResult);
// Receive until the peer closes the connection
do {
iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
if (iResult > 0)
{
printf("Bytes received: %d\n", iResult);
std::cout << recvbuf << std::endl;
}
else if (iResult == 0)
printf("Connection closed\n");
else
printf("recv failed with error: %d\n", WSAGetLastError());
} while (iResult > 0);
// shutdown the connection since no more data will be sent
iResult = shutdown(ConnectSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
printf("shutdown failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
system("pause"); return 1;
}
// cleanup
closesocket(ConnectSocket);
WSACleanup();
return 0;
}
1 Answer 1
At no point in your program are you telling it where to connect to. You are requesting service "7", which of course is resolved to port number 7, but you aren't giving it an IP address or host name to connect to. Ergo, it is trying to connect to port 7 of the same computer that the program is running on - which will fail.
You need to specify the IP address of the WiFi shield as the first parameter to getaddrinfo()
(currently NULL
):
int getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res);
node
specifies either a numerical network address (for IPv4, numbers-and-dots notation as supported byinet_aton(3)
; for IPv6, hexadecimal string format as supported byinet_pton(3)
), or a network hostname, whose network addresses are looked up and resolved. Ifhints.ai_flags
contains theAI_NUMERICHOST
flag, then node must be a numerical network address. TheAI_NUMERICHOST
flag suppresses any potentially lengthy network host address lookups.If the
AI_PASSIVE
flag is not set inhints.ai_flags
, then the returned socket addresses will be suitable for use withconnect(2)
,sendto(2)
, orsendmsg(2)
. If node isNULL
, then the network address will be set to the loopback interface address (INADDR_LOOPBACK
for IPv4 addresses,IN6ADDR_LOOPBACK_INIT
for IPv6 address); this is used by applications that intend to communicate with peers running on the same host.-- Extract from the
getaddrinfo(3)
manual page