Sockets

socket()

 #include<sys/types.h>
 #include<sys/socket.h>
 int socket (int family, int type, int protocol);

family

type

connect()

 int connect ( int sockfd, struct sockaddr *adr );

 struct sockaddr_in {
   unsigned short int sin_family; /* AF_INET */
   unsigned short int sin_port;   /* Port */
   struct in_addr     sin_addr;   /* IP address */
 }

bind()

 int bind( int sockfd, struct sockaddr *address, socklen_t addresslength );

listen()

 int listen( int sockfd, int queue );

accept()

 int accept(int sockfd, struct sockaddr *address, socklen_t addresslength );
returns -1 if an error occurs otherwise the filedescriptor of the socket that accepts the connection.

send()

 ssize_t send( int socketfd, const void *data, size_t data_len, unsigned int flags );
returns -1 if an error occurs otherwise the number of characters which were sent.
 ssize_t recv( int socketfd, void *data, size_t data_len, unsigned int flags );
returns -1 if an error occurs otherwise the number of characters which were received. Take care of the parameter data_len to prevent a buffer overflow danger.

close()

  1. include <unistd.h> int close(int sockfd);

help functions

unsigned short int htons(unsigned short int hostshort); unsigned long int htonl(unsigned long int hostlong); unsigned short int ntohs(unsigned short int netshort); unsigned long int ntohl(unsigned long int netlong);
 #include<netinet/in.h>
  1. include<arpa/inet.h>
 int inet_aton(const char *ptr, struct in_addr *inp);
function inet_addr() is deprecated!
 struct in_addr{ unsigned long int sin_addr; }

If you have different address types than IPv4 than use:

 #include<arpa/inet.>
 int inet_pton(int af, const char *src, void *dst);
 for example like:
 struct in_addr addr;
 inet_pton(AF_INET, "127.0.0.1", &addr);

The other way around

 char* inet_ntoa( struct in_addr in );
this one is not thread safe because of use of a static buffer. So use the following one:
 #include<arpa/inet.h>
 const char* inet_ntop( int af, const void *src, char *dst, socklen_t cnt );

 char buf[16];
 inet_ntop(AF_INET, &addr, buf, 16);

inet_network()

for network part of the ip address.

gethostbyname()

 #include<netdb.h>
 struct hostent *gethostbyname(const char *rechnername );

 struct hostent{
   char*  h_name;
   char** h_aliases;
   short  h_addrtype;
   short  h_length;
   char** h_addr_list;
 }

gethostbyaddr()

 #include<netdb.h>
 struct hostent* gethostbyaddr(const char *ip_addr, int len, int type);

herror()

gives useful information if an error occurs.

Syncronses Multiplexing with select() function

 #include<sys/select.h>
 int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);

You can use FD_SETSIZE sets of file desciptors. To edit these sets use the following functions:

Server example

 int main()
 {
SOCKET acceptSocket; SOCKADDR_IN addr; FD_SET fdSet; SOCKET clients[MAX_CLIENTS]; ...bind()... ...listen()... for(i=0;i<MAX_CLIENTS;i++) {
    clients[i]=INVALID_SOCKET;
  }
  while(1)
  {
    FD_ZERO(&fdSet); 
    /* insert socket that accept the connection try */
    FD_SET(acceptSocket,&fdSet); 
    /* insert sockets that are valid */
    for(i=0;i<MAX_CLIENTS && clients[i]!=INVALID_SOCKET;i++)
        FD_SET(clients[i],&fdSet);
    retval = select(0,&fdSet,NULL,NULL,NULL);
    switch(retval)
    {
    case SOCKET_ERROR:
        print("error");
        break;
    default:
      if(FD_ISSET(acceptSocket,&fdSet)) {
        for(i=0;i<MAX_CLIENTS && clients[i]!=INVALID_SOCKET;i++)
        {
          if(clients[i]==INVALID_SOCKET)
          {
            clients[i]=accept(acceptSocket,NULL,NULL);
            break;
          }
        }
      }
      break;
      /* now test which sockets with valid connections are set in our read set */
      for(i=0;i<MAX_CLIENTS;i++)
      {
      if(clients[i]!=INVALID_SOCKET)
      {
      if(FD_ISSET(clients[i],&fdSet))
      {
        retval=recv(clients[i],buffer,256,0);
        /* 0 means connect had been closed otherwise error */
        if(retval==0 || retval==SOCKET_ERROR)
        {
          close(clients[i]);
          clients[i]=INVALID_SOCKET;
        }
        else
        {
           /* process data that has been received */
        }
      }
    }