[Home] [Credit Search] [Category Browser] [Staff Roll Call] | The LINUX.COM Article Archive |
Originally Published: Tuesday, 30 November 1999 | Author: Daniel Drown |
Published to: develop_articles_tutorials/Development Tutorials | Page: 1/1 - [Printable] |
A Simple Internet Client Application
Daniel Drown shows how to open a connection to a network services. The following article requires basic C knowledge, and file I/O experience.
|
Page 1 of 1 | |
Simple Internet client program - by Dan Drown
Required programming experience: compiling a program, basic C experience, file I/O experience. Summary: An introduction to opening a connection to a network service. Functions used: socket(2) - create an endpoint for communication connect(2) - initiate a connection on a socket read(2) - read from a file descriptor write(2) - write to a file descriptor perror(3) - print a system error message gethostbyname(3) - get the IP for a host herror(3) - print a resolver error message (marked as obsolete???) exit(3) - cause normal program termination memcpy(3) - copy a memory area htons(3) - convert a short integer from host byte order to network byte order. close(2) - closes a file descriptor see also: ip(4) /* Simple Internet client program - by Dan Drown <abob@linux.com> * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * LINUX.COM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include <sys/types.h> /* for socket,connect */ #include <sys/socket.h> /* for socket,connect */ #include <netinet/in.h> /* for htons */ #include <netdb.h> /* for gethostbyname */ #include <string.h> /* for memcpy */ #include <stdio.h> /* for perror */ #include <stdlib.h> /* for exit */ #include <unistd.h> /* for read,write */ void build_inet_addr(struct sockaddr_in *addr, const char *hostname, unsigned short int port); int connect_inet_addr(const char *hostname, unsigned short int port); int main() { int socket_descriptor, returnval; char str[80]; socket_descriptor=connect_inet_addr("localhost", 80); strcpy(str, "HEAD / HTTP/1.0\r\n\r\n"); returnval = write(socket_descriptor, str, strlen(str)); if(returnval < 0) { /* write returns -1 on error */ perror("write(..) error"); exit(1); } if(returnval < strlen(str)) { /* I'm not dealing with this error, regular programs should. */ fprintf(stderr, "the write was short\n"); exit(1); } while((returnval = read(socket_descriptor, str, 80)) > 0) /* write everything to stdout. */ write(STDOUT_FILENO, str, returnval); /* it will be closed anyway when we exit */ close(socket_descriptor); /* just to be pedantic... */ return; } /* IN: hostname, port * OUT: socket descriptor * connects to the hostname:port specified. upon error, it prints a message * and calls exit(2). */ int connect_inet_addr(const char *hostname, unsigned short int port) { int inet_socket; /* socket descriptor */ struct sockaddr_in inet_address; /* IP/port of the remote host to connect to */ build_inet_addr(&inet_address, hostname, port); /* socket(domain, type, protocol) */ inet_socket = socket(PF_INET, SOCK_STREAM, 0); /* domain is PF_INET(internet/IPv4 domain) * * type is SOCK_STREAM(tcp) * * protocol is 0(only one SOCK_STREAM type in the PF_INET domain */ if (inet_socket < 0) { /* socket returns -1 on error */ perror("socket(PF_INET, SOCK_STREAM, 0) error"); exit(2); } /* connect(sockfd, serv_addr, addrlen) */ if(connect(inet_socket, (struct sockaddr *)&inet_address, sizeof(struct sockaddr_in)) < 0) { /* connect returns -1 on error */ perror("connect(...) error"); exit(2); } return inet_socket; } /* IN: hostname, port * OUT: struct sockaddr_in is setup * sets up the sockaddr_in structure. upon error, it prints a message and * calls exit(3). */ void build_inet_addr(struct sockaddr_in *addr, const char *hostname, unsigned short int port) { struct hostent *host_entry; /* gethostbyname(name) */ host_entry = gethostbyname(hostname); if(host_entry == NULL) { /* gethostbyname returns NULL on error */ herror("gethostbyname failed"); exit(3); } /* memcpy(dest, src, length) */ memcpy(&addr->sin_addr.s_addr, host_entry->h_addr_list[0], host_entry->h_length); /* copy the address to the sockaddr_in struct. */ /* set the family type (PF_INET) */ addr->sin_family = host_entry->h_addrtype; /* addr->sin_port = port won't work because they are different byte * orders */ addr->sin_port = htons(port); /* just to be pedantic... */ return; }
| |
Page 1 of 1 |