BSD C API Socket Client Example
The following code shows a simple program to fetch a web page using TCP on a server's port 80 (web server port) and to print the HTTP data to the screen.
int OutputWebPage( char *servName, char* urlDoc) {
int sock;
struct sockaddr_in server; struct hostent *hp; char buffer[1024]; // create socket sock = socket(AF_INET, SOCK_STREAM, 0);
fprintf(stderr,"Error opening stream socket\n");
// Connect socket using name specified by command line server.sin_len = sizeof(server); server.sin_family = AF_INET; hp = gethostbyname(servName);
fprintf(stderr, "%s: unknown host\n", argv[1]);
memcpy((char *)&server.sin_addr, (char *)hp->h_addr, hp->h_length); server.sin_port = hton(80); // set to well-known HTTP server port 80
if (connect(sock, (struct sockaddr *)&server, sizeof(server)) < 0) {
fprintf(stderr,"Error connecting stream socket");
2 P.I.P.S. stands for P.I.P.S. Is POSIX on Symbian OS. The P.I.P.S. libraries provide libc, libdl, libm, and libpthread for Symbian OS v9, replacing the previous partial support for standard C on Symbian OS offered by estlib.
More information about P.I.P.S. can be found on the Symbian Developer Network wiki (http://developer.symbian.com/wiki/display/oe/P.I.P.S.+Home).
// send a HTTP GET to web server sprintf(buffer, "GET %s\n", urlDoc);
printf(stderr,"Error on send().\n"); close(Socket);
// Receive the file contents and print to stdout while(1) {
// Wait to receive, nRet = NumberOfBytesReceived nRet = recv(sock, buffer, sizeof(buffer), 0); if (nRet <= 0) break;
close(sock);
In this example, the function OutputWebPage() retrieves a web page from the server specified in the first argument, accessing the source with the specified URL document name (blank just gets the home page). An example invocation is:
OutputWebPage( www.yahoo.com," ");
which retrieves and prints the HTML source of Yahoo's home page.
Creating the socket
First, the client socket is created by the line:
This creates a TCP socket to be used in communicating with the web server. The function socket() is prototyped as follows:
int socket(int domain, int type, int protocol)
where domain is AF_INET for TCP/IP, type is SOCKJ3TREAM for TCP or S0CK_DATAGRAM for UDP, and protocol indicates the specific protocol for the type. In this case, protocol can be set to zero, since TCP and UDP are the only protocols in AF_INET for those types.
socket() returns an integer handle for the socket, which is used as a reference in subsequent socket function calls.
Converting domain names to IP addresses
Next, the server name is converted to an IP address as follows:
server.sin_len = sizeof(server); server.sin_family = AF_INET; hp = gethostbyname(servName);
fprintf(stderr, "%s: unknown host\n", argv[1]);
memcpy((char *)&server.sin_addr, (char *)hp->h_addr, hp->h_length); server.sin_port = hton(80); // set to well-known HTTP server port 80
IP addresses are hard for people to remember, so ASCII names - known as domain names-are used instead. It's much easier to remember www.yahoo.com, for example, than it is to remember 216.109.118.77.
The BSD function gethostbyname() converts the server name to an IP address using what is known as the Domain Name System (DNS). DNS is a service used in TCP/IP networks, which translates human-readable domain names to IP addresses. DNS is a complex system due to the billions of IP addresses in use, which change every day - but fortunately as a network programmer, it is easy to use.
The port address (server. sin_port) is set to 80, which is the port number for HTTP web pages.
Connecting the socket
Now that the software has the IP address and port, it performs a TCP connection to the server's HTTP endpoint as follows:
if (connect(sock, (struct sockaddr *)&server, sizeof(server)) < 0) {
fprintf(stderr,"Error connecting stream socket");
The function connect() connects a socket whose handle is specified as the first argument, to a destination endpoint whose address is specified in the second argument (with the address structure's size specified in argument three). For TCP this consists of a packet exchange between the endpoints to establish a virtual connection.
In the case of UDP, this connect() just associates the socket with the destination address so that the programmer need not supply the address on each send. In this example, we are establishing a TCP connection, however.
The hardest part about using connect() is setting up the data structures to specify the endpoint address to connect to. I will not go into the data structure in detail here, but the form of address setup shown in the example is fairly typical.
Sending data
Next, the HTTP GET request is sent to the server through the connected socket as follows:
nRet = send(socket, buffer, strlen(buffer), 0);
send() is used to send a buffer to the remote endpoint through the socket whose handle is passed as the first argument. It has the form:
int send(int socket, const void *buff, size_t len, int flags);
send() returns the number of bytes sent. If it is a negative number, then an error occurred.
For UDP sockets, you can use sendto() for sending UDP packets. It is the same as send() except you specify the address of the endpoint to send the data to. It is defined as:
int sendto(int s, const void *msg, size_t len, int flags, const struct sockaddr *to, socklen_t tolen);
Receiving data
When the server gets the HTTP GET request, it will start sending the web page to the client. The example retrieves this data and prints it to the screen, using the following lines of code:
// Wait to receive, nRet = NumberOfBytesReceived nRet = recv(sock, buffer, sizeof(buffer), 0); if (nRet <= 0) break;
recv() is used for TCP sockets (or UDP sockets in which connect() was called) to receive data. The data is then placed in a supplied buffer. recv() returns the number of bytes received (if this is zero it means the connection was terminated, if negative an error occurred). It has the form:
int recv(int socket, void *buffer, size_t length, int flags);
In the case of UDP sockets, you usually use recvfrom(). It's the same as recv() except it returns the address of the endpoint that sent the packet. It has the form:
int recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen);
Cleaning up the connection
Once the web page retrieval is complete, the socket is cleaned up as follows:
close(sock);
close(int socket) closes the socket and shuts down the connection. A function called shutdown(), prototyped as int shutdown(int s, int how), also exists to shut down a specific direction of the session. The parameter how has three possible values: SHUT_RD disallows further reception; SHUT_WR disallows further transmission; and SHUT_RDWR disallows both reception and transmission.
Post a comment