Applying C - Sockets The Client |
Written by Harry Fairhead | ||||||||
Tuesday, 26 April 2022 | ||||||||
Page 4 of 4
Connecting Using a URLThere is also a utility function that will perform a DNS lookup for you or convert an IP address specified so you don't need to specify an IP address struct. Surprisingly this is almost an easier way to do things and it has become the standard way to set up a socket. The getaddrinfo function not only looks up the URL using DNS, it also constructs all of the structs you need to open a socket and connect. It will also return as many address specifications as you request, IPv4 and IPv6 for example. The function specification is: int getaddrinfo(const char *node, and you need to add: #include <netdb.h> If you compile with C99 or C11 selected then you will find that none of the following works. You need to add: #define _GNU_SOURCE to the start of the file. You pass getaddrinfo the IP address or the DNS name, i.e. either "93.184.216.34" or "www.example.com", as node. The service can be specified as a port address "80" or as a service name "http". The hints struct is used to specify what sort of socket and address you are going to use. The result is a linked list of structs pointed at by addrinfo. The only slightly complication in using getaddrinfo is that you might have more than one result - one for IPv4 and one for IPv6, say - and then you have to work out which one to actually use. The result struct contains structs that you need to both open the socket and to connect. For example, setting up the hints as: struct addrinfo hints; asks for structs to be made for a TCP IPv4 socket. We can now get the address details we need: struct addrinfo *servinfo; Notice that you could use the IP address as a string. As long as this works the result should be a linked list with a single entry. In this case servinfo points to the first and only addrinfo struct. If there are any additional structs they are pointed at by: servinfo->next which is NULL if there is no next struct. Using the single result is easy. To create the socket we use: int sockfd = socket(servinfo->ai_family, and to connect to the server we use: connect(sockfd, This is so much simpler that whenever you need a socket connected to a given URL or IP address and port you tend to fall into the idiom of writing: struct addrinfo hints; memset(&hints, 0, sizeof hints); hints.ai_family = AF_INET ; hints.ai_socktype = SOCK_STREAM; struct addrinfo *servinfo; int status = getaddrinfo("www.example.com", "80", The only minor complication is that you need to remember to free the linked list once you are finished with it using: freeaddrinfo(servinfo); As before this all works on any POSIX system including Linux on x86, Raspbian and so on. It doesn’t work without some modifications under Windows, even with the help of MinGW. To make it work you need to add: #define _WIN32_WINNT 0x501 #include <ws2tcpip.h> to the start of the file and add the library file ws2_32.a, which you should find in mingw/lib, to the libraries. The complete POSIX listing is: #define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/socket.h> #include <string.h> #include <sys/types.h> #include <netinet/in.h> #include <netdb.h> int main(int argc, char** argv) { struct addrinfo hints; memset(&hints, 0, sizeof hints); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; struct addrinfo *servinfo; int status = getaddrinfo("www.example.com", "80",&hints, &servinfo); int sockfd = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol); connect(sockfd, servinfo->ai_addr, servinfo->ai_addrlen); char header[] = "GET /index.html In chapter but not in this extract
Summary
Related ArticlesRemote C/C++ Development With NetBeans Getting Started With C/C++ On The Micro:bit To be informed about new articles on I Programmer, sign up for our weekly newsletter, subscribe to the RSS feed and follow us on Twitter, Facebook or Linkedin.
Comments
or email your comment to: comments@i-programmer.info |
||||||||
Last Updated ( Tuesday, 26 April 2022 ) |