IPv6 client can't connect to IPv6 server - c++

My program is client server IPv6. the client can't make connection to the server? The client and server must use loop-back address
the problem in this code its can't connect to the server
SOCKET sock = socket(AF_INET6, SOCK_STREAM, 0);
if (sock == INVALID_SOCKET)
{
cerr << "Can't create socket, Err #" << WSAGetLastError() << endl;
WSACleanup();
return;
}
sockaddr_in6 hint;
hint.sin6_family = AF_INET6;
hint.sin6_port = htons(port);
hint.sin6_addr = in6addr_any;
// Connect to server
int connResult = connect(sock, (sockaddr*)&hint, sizeof(hint));
if (connResult == SOCKET_ERROR)
{
cerr << "Can't connect to server, Err #" << WSAGetLastError()
<< endl;
closesocket(sock);
WSACleanup();
return;
}

A client TCP socket cannot connect() to in6addr_any. A TCP server can bind() to in6addr_any so it can then listen() on all available local IPv6 network interfaces with a single SOCKET. But the client must connect() to a real IPv6 address that the server is actually listening on (such as in6addr_loopback if the client is running on the same machine as the server. Your server can use GetAdaptersInfo() or GetAdaptersAddresses() to discover what its local IP addresses actually are that are valid for the client to connect() to).
Also, you need to zero out the sockaddr_in6 struct completely. sockaddr_in6 has sin6_flowinfo and sin6_scope_id fields that you are not populating, so they will have random values from the stack. sin6_scope_id in particular will affect connect()'s ability to use the correct network interface to connect to the server.
SOCKET sock = socket(AF_INET6, SOCK_STREAM, 0);
if (sock == INVALID_SOCKET)
{
cerr << "Can't create socket, Err #" << WSAGetLastError() << endl;
WSACleanup();
return;
}
sockaddr_in6 hint = {};
hint.sin6_family = AF_INET6;
hint.sin6_port = htons(port);
inet_pton(AF_INET6, "server IPv6 address here", &(hint.sin6_addr));
// Connect to server
int connResult = connect(sock, (sockaddr*)&hint, sizeof(hint));
...
Consider using getaddrinfo() instead. Let the OS allocate a properly-populated sockaddr_in6 for you, which you can then pass as-is to connect() (similarly to how I explained to you in your previous question for bind()).
addrinfo hint = {};
hint.ai_family = AF_INET6;
hint.ai.socktype = SOCK_STREAM;
hint.ai_protocol = IPPROTO_TCP;
addrinfo *res;
err = getaddrinfo("server hostname or IPv6 address here", "server port here", &hint, &res);
if (err != 0)
{
cerr << "Can't get address to connect, Err #" << WSAGetLastError() << endl;
WSACleanup();
return;
}
SOCKET sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (sock == INVALID_SOCKET)
{
cerr << "Can't create socket, Err #" << WSAGetLastError() << endl;
freeaddrinfo(res);
WSACleanup();
return;
}
// Connect to server
int connResult = connect(sock, res->ai_addr, res->ai_addrlen);
if (connResult == SOCKET_ERROR)
{
cerr << "Can't connect to server, Err #" << WSAGetLastError() << endl;
closesocket(sock);
freeaddrinfo(res);
WSACleanup();
return;
}
freeaddrinfo(res);
...

Related

Error "Invalid padding length on received packet" when connecting to winsock server using PuTTY

I'm mostly new to new to networking so I thought I'd start with something simple so I was trying to make a simple C++ echo server. I'm using PuTTY for testing. When I connect to the server through PuTTY I get a PuTTY error of
Invalid padding length received packet
When I check the server console it says that the PuTTY client connected but disconnected immediatelly.
Here's my code.
#include <stdlib.h>
#include <WS2tcpip.h> //includes the winsock file as well
#include <string>
#pragma comment (lib,"ws2_32.lib")
#define PORT 17027
int main()
{
//Initialize winsock
WSADATA wsData;
WORD ver = MAKEWORD(2, 2);
int wsOK = WSAStartup(ver, &wsData);
if (wsOK != 0)
{
std::cout << "Can't initialize wonsock! Quitting" << std::endl;
return 0;
}
//Create a socket
SOCKET listenSocket = socket(AF_INET, SOCK_STREAM, 0);
if (listenSocket == INVALID_SOCKET)
{
std::cout << "Can't create socket! Quitting" << std::endl;
return 0;
}
//Bind the socket to an ip address and port
sockaddr_in hint;
hint.sin_family = AF_INET;
hint.sin_port = htons(PORT);
hint.sin_addr.S_un.S_addr = INADDR_ANY;
bind(listenSocket, (sockaddr *)&hint, sizeof(hint));
//Tell Winsock the socket is for listening
listen(listenSocket, SOMAXCONN);
//Wait for connection
sockaddr_in client;
int clientSize = sizeof(client);
SOCKET clientSocket = accept(listenSocket, (sockaddr*)&client, &clientSize);
if (clientSocket == INVALID_SOCKET)
{
std::cout << "Cant accept client! Quitting" << std::endl;
return 0;
}
char host[NI_MAXHOST]; // Client's remote name;
char service[NI_MAXHOST]; // Client's (i.e. port) the client is connected on
ZeroMemory(host, NI_MAXHOST);
ZeroMemory(service, NI_MAXHOST);
if (getnameinfo((sockaddr*)&client, sizeof(client), host, NI_MAXHOST, service, NI_MAXHOST, 0) == 0) // try to get name of client
{
std::cout << host << " connected on port " << service << std::endl;
}
else
{
inet_ntop(AF_INET, &client.sin_addr, host, NI_MAXHOST); //get address of client
std::cout << host << " connected on port " << ntohs(client.sin_port) << std::endl;
}
//Close listening socket
closesocket(listenSocket);
//While loop: accept and echo message back to client
char buf[4096];
while (true)
{
ZeroMemory(buf, 4096);
//Wait for client to send data
int bytesReceived = recv(clientSocket, buf, 4096, 0);
if (bytesReceived == SOCKET_ERROR)
{
std::cerr << "Error in recv(). Quitting" << std::endl;
break;
}
if (bytesReceived == 0)
{
std::cerr << "Client disconnected" << std::endl;
break;
}
//Echo message back to client
send(clientSocket, buf, bytesReceived + 1, 0);
}
//Close the socket
closesocket(clientSocket);
//Cleanup winsock
WSACleanup();
return 0;
}
It looks like you are trying to connect with SSH. Your code is not an SSH server.
To connect to a raw socket server with PuTTY, you need to select the "Raw" connection type.

winsock server send and receive simultaniously

I'm new to WinSock, and I'm trying something out. I have client and server programs that are communicating with each other. If the client types something, the server will just echo it back. I want them to receive and send at the same time, so I put the client in non-blocking mode, and it works kind-of OK. But when I try to put the server in non-blocking, it crashes saying that recv() == SOCKET_ERROR.
So the question is : why can the client work in non-blocking, but the server can't? How can I solve this?
TCP_SERVER:
#include <iostream>
#include <WS2tcpip.h>
#include <Windows.h>
#pragma comment (lib,"ws2_32.lib")
using namespace std;
string receive(SOCKET clientSocket, char* buf)
{
ZeroMemory(buf, 4096);
int bytesReceived = recv(clientSocket, buf, 4096, 0);
string bufStr = buf;
cout << "bytes received: " << bytesReceived << endl;
if (bytesReceived == SOCKET_ERROR)
{
cerr << "error met recv() in de reciev() functie" << endl;
exit(EXIT_FAILURE);
}
if (bytesReceived == 0)
{
cout << "client disconnected" << endl;
exit(EXIT_FAILURE);
}
return bufStr;
}
void main()
{
//initialize winsock
WSADATA wsData;
WORD ver = MAKEWORD(2, 2);
int wsOk = WSAStartup(ver, &wsData);
if (wsOk != 0) {
cerr << "can't initialize winsock ABORT";
return;
}
//create socket
SOCKET listening = socket(AF_INET, SOCK_STREAM, 0);
if (listening == INVALID_SOCKET) {
cerr << "cant create socket ABORT" << std::endl;
}
//bind IP adress and port to socket
sockaddr_in hint;
hint.sin_family = AF_INET;
hint.sin_port = htons(54000);
hint.sin_addr.S_un.S_addr = INADDR_ANY; //could also inet_pton
bind(listening, (sockaddr*)&hint, sizeof(hint));
//tell winsock the socket is for listening
listen(listening, SOMAXCONN);
//wait for connection
sockaddr_in client;
int clientSize = sizeof(client);
SOCKET clientSocket = accept(listening, (sockaddr*)&client, &clientSize);
if (clientSocket == INVALID_SOCKET) {
cerr << "somthing went wrong with client socket accept ABORT";
exit(EXIT_FAILURE);
}
char host[NI_MAXHOST]; //client remote name
char service[NI_MAXSERV]; //service (i.e port) the client is connected on
ZeroMemory(host, NI_MAXHOST);
ZeroMemory(service, NI_MAXSERV);
if (getnameinfo((sockaddr*)&client, sizeof(client), host, NI_MAXHOST, service, NI_MAXSERV, 0) == 0)
{
cout << host << " connected on port " << service << endl;
}
else {
inet_ntop(AF_INET, &client.sin_addr, host, NI_MAXHOST);
cout << host << " connected on port " << ntohs(client.sin_port) << endl;
}
//close listening socket
closesocket(listening);
//non blocking socket leads to error
u_long mode = 1; // 1 to enable non-blocking socket
ioctlsocket(clientSocket, FIONBIO, &mode);
//non blocking socket
//while loop: accept and echo message to client
char buf[4096];
string inputTxt;
while (true)
{
inputTxt = receive(clientSocket,buf);
send(clientSocket, buf, inputTxt.size() + 1, 0);
}
closesocket(clientSocket);
WSACleanup();
}
TCP_CLIENT:
#include <iostream>
#include <WS2tcpip.h>
#include <Windows.h>
#pragma comment (lib,"ws2_32.lib")
using namespace std;
string receive(SOCKET clientSocket, char* buf)
{
ZeroMemory(buf, 4096);
int bytesReceived = recv(clientSocket, buf, 4096, 0);
string bufStr = buf;
cout << "bytes received: " << bytesReceived << endl;
if (bytesReceived == SOCKET_ERROR)
{
cerr << "error met recv() in de reciev() functie" << endl;
exit(EXIT_FAILURE);
}
if (bytesReceived == 0)
{
cout << "client disconnected" << endl;
exit(EXIT_FAILURE);
}
return bufStr;
}
void main()
{
//initialize winsock
WSADATA wsData;
WORD ver = MAKEWORD(2, 2);
int wsOk = WSAStartup(ver, &wsData);
if (wsOk != 0) {
cerr << "can't initialize winsock ABORT";
return;
}
//create socket
SOCKET listening = socket(AF_INET, SOCK_STREAM, 0);
if (listening == INVALID_SOCKET) {
cerr << "cant create socket ABORT" << std::endl;
}
//bind IP adress and port to socket
sockaddr_in hint;
hint.sin_family = AF_INET;
hint.sin_port = htons(54000);
hint.sin_addr.S_un.S_addr = INADDR_ANY; //could also inet_pton
bind(listening, (sockaddr*)&hint, sizeof(hint));
//tell winsock the socket is for listening
listen(listening, SOMAXCONN);
//wait for connection
sockaddr_in client;
int clientSize = sizeof(client);
SOCKET clientSocket = accept(listening, (sockaddr*)&client, &clientSize);
if (clientSocket == INVALID_SOCKET) {
cerr << "somthing went wrong with client socket accept ABORT";
exit(EXIT_FAILURE);
}
char host[NI_MAXHOST]; //client remote name
char service[NI_MAXSERV]; //service (i.e port) the client is connected on
ZeroMemory(host, NI_MAXHOST);
ZeroMemory(service, NI_MAXSERV);
if (getnameinfo((sockaddr*)&client, sizeof(client), host, NI_MAXHOST, service, NI_MAXSERV, 0) == 0) {
cout << host << " connected on port " << service << endl;
}
else {
inet_ntop(AF_INET, &client.sin_addr, host, NI_MAXHOST);
cout << host << " connected on port " << ntohs(client.sin_port) << endl;
}
//close listening socket
closesocket(listening);
/*
//non blocking socket leads to error
u_long mode = 1; // 1 to enable non-blocking socket
ioctlsocket(clientSocket, FIONBIO, &mode);
//non blocking socket
*/
//while loop: accept and echo message to client
char buf[4096];
string inputTxt;
while (true)
{
inputTxt = receive(clientSocket,buf);
send(clientSocket, buf, inputTxt.size() + 1, 0);
}
closesocket(clientSocket);
WSACleanup();
}
You are not handling the case where send()/recv() are failing due to a WSAEWOULDBLOCK error, which is NOT a fatal error. It just means there is no work to be done at that moment, try again later.
For recv(), that means there are no bytes available to read from the socket's receive buffer. The socket will be in a readable state when there are bytes available to read from it, or the peer has performed a graceful disconnect.
For send(), it means the peer's receive buffer is full and can't receive new bytes until the peer reads some bytes to clear up buffer space. Any unsent bytes will have to be passed to send() again at a later time. The socket will be in a writable state when new bytes can be sent to the peer, and not in a writable state when the peer's buffer is full.
When your server accepts a client and tries to receive() from it, recv() is going to keep failing with WSAEWOULDBLOCK until the client actually sends something.
So, you need to handle WSAEWOULDBLOCK properly and retry as needed. Or better, use select() (or WSAAsyncSelect(), or WSAEventSelect(), or Overlapped I/O) to detect the socket's actual state to know when send()/recv() can be safely called without causing an WSAEWOULDBLOCK error.

I coded a c++ server/client program using windows sockets. getting 10061 from wsagetlasterror() trying to connect using my public ip addr

Im attempting to connect to my server via my client and if i use my local host address 127.0.0.1 everything works perfectly fine. it connects and im able to send data. however whenever i switch it to my public address it fails to connect. i already went through my router and forwarded the port im using. and ive tested if the port is open with canyouseeme.org and port forward network utilities. the error code i get from getlasterror() is 10061. i also called my isp and they told me the port is open so i should be able to connect but im not. i turned off my firewall and AV as well. i have windows 10 64 bit. im at a loss and would really appreciate the help. the error code means that the server is actively refusing the connection. but nothing happens on my server side...it stays in the accept() call.
this is the server code. how do i solve this issue? i currently have both the server and client on one computer.
class Server
{
public:
Server(int port)
:
port(port)
{
std::cout << "Initializing server...\n";
if (WSAStartup(version, &wsData) == 0)
{
auto result = createListenSock();
//if no value is returned, it was a success
if (!result.has_value())
std::cout << "Successfully created a server! Accepting Clients now.\n";
else
std::cout << result.value() << std::endl;
}
else
std::cout << "Failed to initialize WinSock. Error : " << WSAGetLastError() << std::endl;
}
~Server()
{
closesocket(listensock);
closesocket(client);
WSACleanup();
}
std::optional<std::string> acceptClient()
{
int sz = sizeof(clientinfo);
if ((client = accept(listensock, (sockaddr*)&clientinfo, &sz)) == INVALID_SOCKET)
return {};
else
{
char clientipaddr[100];
inet_ntop(AF_INET, &clientinfo.sin_addr, clientipaddr, sizeof(clientipaddr));
return std::string(clientipaddr);
}
}
private:
std::optional<std::string> createListenSock()
{
//AF_INET for ipv4
//SOCK_STREAM A socket type that provides sequenced, reliable, two-way,
//connection-based byte streams with an OOB data transmission mechanism.
if ((listensock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
return "Failed to created listen socket...\n";
initConnectionInfo();
if (bind(listensock, (sockaddr*)&serverInfo, sizeof(serverInfo)) == SOCKET_ERROR)
return "Failed to bind...\n";
if (listen(listensock, SOMAXCONN) == SOCKET_ERROR)
return "Failed to put into listening mode...\n";
//if it returns an empty container, that means it was successful
return {};
}
void initConnectionInfo()
{
//make it use ipv4
serverInfo.sin_family = AF_INET;
//htons converts the port from host to network byte order.
serverInfo.sin_port = htons(port);
//specify that we can accept any ip address
serverInfo.sin_addr.S_un.S_addr = INADDR_ANY;
}
private:
WSADATA wsData;
int version = MAKEWORD(2,2);
SOCKET listensock;
sockaddr_in serverInfo;
int port;
private:
//client variables
SOCKET client;
sockaddr_in clientinfo;
};
int main()
{
//create server
Server server(1024);
auto clientip = server.acceptClient();
if (!clientip.has_value())
{
std::cout << "Couldn't connect to client.";
system("pause");
return 0;
}
std::cout << "Connected to client!" << std::endl << "Client IP Address: " << clientip.value() << std::endl;
and this is the client code
SOCKET startclient()
{
WSADATA data;
//server to connect to
std::string ipAddress = "127.0.0.1"; //IF I CHANGE THIS TO MY PUBLIC IP ADDRESS IT FAILS TO CONNECT
int port = 1024;
// initialize winsock
if (WSAStartup(MAKEWORD(2, 2), &data) != 0)
{
std::cout << "Could not initialize WinSock...\n";
return SOCKET_ERROR;
}
//create a socket
SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == INVALID_SOCKET)
{
std::cout << "Couldn't create a socket, Error " << WSAGetLastError() << std::endl;
WSACleanup();
return SOCKET_ERROR;
}
//this tells our socket what info to use to connect to the server
sockaddr_in serverinfo;
serverinfo.sin_family = AF_INET;
//htons converts the port number from host to network byte order
serverinfo.sin_port = htons(port);
inet_pton(AF_INET, ipAddress.c_str(), &serverinfo.sin_addr);
std::cout << "Attempting to connect..." << std::endl;
if (connect(sock, (sockaddr*)&serverinfo, sizeof(serverinfo)) == SOCKET_ERROR)
{
std::cout << "Failed to connect... Error : " << WSAGetLastError() << std::endl;
WSACleanup();
closesocket(sock);
return SOCKET_ERROR;
}
else
std::cout << "Connected!" << std::endl;
return sock;
}
int main()
{
SOCKET client = startclient();
if (client == SOCKET_ERROR)
{
system("pause");
return 0;
}

how can i bind socket to ipv6 address?

I am trying to port ipv4 applications to ipv6 but I can't bind the socket to the ipv6 address.
The problem is here:
err=bind(listening, (sockaddr*)&hint, sizeof(hint));
The err should be 0 but in this code it returns -1. What is going wrong ?
SOCKET listening = socket(AF_INET6, SOCK_STREAM, 0);
if (listening == INVALID_SOCKET)
{
cerr << "Can't create a socket! Quitting" << endl;
return;
}
int err;
// Bind the ip address and port to a socket
sockaddr_in6 hint;
hint.sin6_family = AF_INET6;
hint.sin6_flowinfo = 0;
hint.sin6_port = htons(54000);
hint.sin6_addr = in6addr_any;
err=bind(listening, (sockaddr*)&hint, sizeof(hint)); //<======= here
Rather than populate the sockaddr_in6 manually, you can (and should) use getaddrinfo() instead and let it allocate a properly filled sockaddr_in6 for you, eg:
int err;
SOCKET listening = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
if (listening == INVALID_SOCKET)
{
err = WSAGetLastError(); // or errno on non-Windows platforms...
cerr << "Can't create a socket! Error " << err << ". Quitting" << endl;
return;
}
// Bind the ip address and port to a socket
addrinfo hint = {};
hint.ai_flags = AI_NUMERICHOST | AI_PASSIVE;
hint.ai_family = AF_INET6;
hint.ai_socktype = SOCK_STREAM;
hint.ai_protocol = IPPROTO_TCP;
addrinfo *res;
err = getaddrinfo("::0", "54000", &hint, &res);
if (err != 0)
{
cerr << "Can't get address to bind the socket! Error " << err << ". Quitting" << endl;
closesocket(listening); // or close() on non-Windows platforms...
return;
}
err = bind(listening, res->ai_addr, res->ai_addrlen);
if (err == SOCKET_ERROR)
{
err = WSAGetLastError(); // or errno on non-Windows platforms...
cerr << "Can't bind the socket! Error " << err << ". Quitting" << endl;
freeaddrinfo(res);
closesocket(listening); // or close() on non-Windows platforms...
return;
}
freeaddrinfo(res);
...
This might depend on your platform, but on Linux since 2.4 the sockaddr_in6 structure also contains a sin6_scope_id member for defining the IPv6 scope, and since the variable hint is on the stack, it's got random data in it.
The IPv6 scope describes what kind of address it is: unicast, multicast, link local, and a few others, and I have only a drive-by knowledge of them. But if there's garbage in there, it could be a thing.
Recommend ruling this out as an issue by either hard-setting sin6_scope_id to zero, or (better) just zero out the entire sockaddr_in6 structure before assigning stuff to it; I've long done this with my sockaddr_in variables just to be sure I didn't end up with junk I didn't want.
memset(&hint, 0, sizeof hint);
And yes, the errno is really important.

C++ Sockets recv() syscall returning -1

I'm currently having a problem passing messages between a server and client.
As far as I know, I am properly following best practices for socket programming outlined by Beej's Socket Programming Tutorial.
When I run the two processes, the recv() syscall returns -1 (an error), rather than the number of bytes received. Also when trying to output the buf, there are a bunch of gobbledygook characters. Which makes sense, because of the error.
I'm wondering if someone could steer me in the right direction as to why I am having issues with recv()? The following are relevant code snippets.
Server:
struct sockaddr_storage their_addr;
socklen_t addr_size;
int sockfd, newfd, byte_count, status;
char buf[512];
struct addrinfo hints, *res;
// first, load up address structs with getaddrinfo():
memset(&hints, 0, sizeof hints);
hints.ai_family = PF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// get address info, print stuff if error
if((status = getaddrinfo("nunki.usc.edu", "21957", &hints, &res)) !=0){
fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
exit(1);
}
// make a socket:
if((sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) == -1){
cout << "socket fail" << endl;
}
// bind the socket to the port
bind(sockfd, res->ai_addr, res->ai_addrlen);
// required output
cout << "Phase1: Login server has TCP port number " << "21957 "
<< "and IP address " << getIPfromHost("nunki.usc.edu") << endl;
// listen for incoming connections
listen(sockfd, 10);
cout << "after listen" << endl;
// halt until receipt
addr_size = sizeof(their_addr);
newfd = accept(sockfd, (struct sockaddr *)&their_addr, &addr_size);
cout << "after accept" << endl;
// Now that we're connected, we can receive some data
byte_count = recv(sockfd, buf, sizeof buf, 0);
printf("recv()'d %d bytes of data in buf\n", byte_count);
printf("Msg is %s\n", buf);
Client:
struct addrinfo hints, *res;
int sockfd;
// first, load up address structs with getaddrinfo():
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
getaddrinfo("nunki.usc.edu", "21957", &hints, &res);
// make a socket:
if((sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) == -1){
cout << "socket fail" << endl;
}
// attempt connection to port
if(connect(sockfd, res->ai_addr, res->ai_addrlen) == -1){
cout << "connect fail" << endl;
}
// send message to server
cout << "sockfd " << sockfd << endl;
int byte_count = send(sockfd, "Hello", 5, 0);
cout << byte_count << endl;
The following is the output for Server:
Phase1: Login server has TCP port number 21957 and IP address 68.181.201.3
after listen
after accept
recv()'d -1 bytes of data in buf
Msg is ÿhÿ?sÈ
Glæ
The following is the output for Client:
sockfd 4
5
You are calling recv on the wrong socket. You need to recv on newfd:
byte_count = recv(newfd, buf, sizeof buf, 0); /* newfd instead of sockfd. */
Now that that's out of the way,
As far as I know, I am properly following best practices for socket
programming
I completely disagree.
You are not checking return statuses for listen, bind, getaddrinfo etc
There's not strerror or perror in your program
You want to recv() using the socket returned from accept()
byte_count = recv(newfd, buf, sizeof buf, 0);
Maybe I shouldn't write this as an answer, but as a comment. Nevertheless, IMHO your use of getaddrinfo() seems wrong to me.
On the client side, it is supposed to be called and then iterated through the results until a connection can be established.
so
struct addrinfo * r2
sockfd = -1;
for (r2=res; r2; r2=r2->ai_next) {
// make a socket:
if((sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) == -1){
continue; // next result
}
// attempt connection to port
if(connect(sockfd, res->ai_addr, res->ai_addrlen) == -1){
close(sockfd);
sockfd = -1;
continue;
}
}
if (sockfd == -1) {
// do error handling
}
In this way, you can check all possible connections.
On the server side, it is rather unusual to use getaddrinfo(). Normally, you would create an IPv6 socket and enable it to listen for IPv4 as well by using setsockopt() to unset the IPV6_V6ONLY flag. In this way, the socket listens to both IPv6 and IPv4. (Alas, not on WIndows XP AFAIK.)
The sockfd is just useed for listening the clients, newfd is used for data transmitting.