Socket programming is not a difficult one in much of high level languages. I have used sockets in Java several times and the stuff were running like a charm. Unfortunately, same easiness is not current for C. However, it is the faster way of doing this work.
Last day, I needed to code a client socket for retrieving some data over the network. My Ubuntu was ready for the task with its installed C libraries. Since Linux sockets are a little bit detailed so there were too many terms (htons, inet_ntoa) which requires some low level knowledge of Linux sockets. For example, a C# programmer does not need to know how Windows converts an IP number to binary data and via versa. But Linux sockets are harder. But once you learn it, it is more fun.
Finally, I wrote a small library for a client socket task. The example of this code is shown below:
(Test.c)
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "ClientSocket.h"
- int main(int argc, char** argv) {
- /* We will store some text in this buffer */
- int bufsize=1024;
- char buffer[bufsize];
- char *hostname = "blogspot.com";
- int port = 80;
- /* Getting ip address of google.com into buffer */
- getIPAddress("google.com", buffer);
- printf("Connecting to (%s) %s\n", hostname, buffer);
- /* Creating socket */
- struct ClientSocket *socket = socket_create(buffer, port);
- /* Connecting */
- socket_connect(socket);
- /* Sending a http request */
- strcpy(buffer,"GET /\n\n");
- socket_send(socket, buffer, strlen(buffer));
- /* Receiving the first #bufsize elements */
- socket_receive(socket, buffer, bufsize);
- printf("%s",buffer);
- /* Do not read any more. Closing */
- socket_close(socket);
- return (EXIT_SUCCESS);
- }
The header file of out tiny library is here:(ClientSocket.h)
The C source file of our tiny library is here: (ClientSocket.c)
- /*
- * File: ClientSocket.h
- * Author: Practical Code Solutions
- *
- * Created on January 31, 2012, 9:56 AM
- */
- #ifndef CLIENTSOCKET_H
- #define CLIENTSOCKET_H
- #ifdef __cplusplus
- extern "C" {
- #endif
- struct ClientSocket {
- int fd;
- char *ip;
- int port;
- int (*getIp)(const char *, char *);
- };
- int getIPAddress(const char *host, char *ip);
- struct ClientSocket *socket_create(char *ip, int port);
- int socket_connect(struct ClientSocket *sock);
- int socket_send(struct ClientSocket *sock, char *data, int len);
- int socket_receive(struct ClientSocket *sock, char *data, int len);
- int socket_close(struct ClientSocket *sock);
- #ifdef __cplusplus
- }
- #endif
- #endif /* CLIENTSOCKET_H */
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <arpa/inet.h>
- #include <sys/socket.h>
- #include <netdb.h>
- #include "ClientSocket.h"
- int getIPAddress(const char *host, char *ip){
- struct hostent *hh = gethostbyname(host);
- struct in_addr *add = hh->h_addr_list[0];
- strcpy(ip, inet_ntoa(add[0]));
- }
- struct ClientSocket *socket_create(char *ip, int port){
- struct ClientSocket *socket = malloc(sizeof(struct ClientSocket));
- socket->ip = ip;
- socket->port = port;
- socket->getIp = getIPAddress;
- return(socket);
- }
- int socket_connect(struct ClientSocket *sock){
- struct sockaddr_in addr;
- int result;
- sock->fd = socket(AF_INET, SOCK_STREAM, 0);
- memset((char *)&addr, 0, sizeof(addr));
- addr.sin_port = htons(sock->port);
- addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = inet_addr(sock->ip);
- result = connect(sock->fd, (struct sockaddr *)&addr, sizeof(addr));
- return(result);
- }
- int socket_send(struct ClientSocket *sock, char *data, int len){
- return send(sock->fd, data, len, 0);
- }
- int socket_receive(struct ClientSocket *sock, char *data, int len){
- data[len-1] = '\0';
- return recv(sock->fd, (void *)data, len -1 , 0);
- }
- int socket_close(struct ClientSocket *sock){
- return close (sock->;fd);
- }
Little long but really very helpful information you have shared here.
ReplyDeleteI'll try to use your code.
ReplyDeleteThanks!
-Marco