Penguin
Note: You are viewing an old revision of this page. View the current version.

This is to describe how to write networking programs in C using the BSD Socket Layer API. This mostly applies to almost all other languages with only minor modifications. This is an updated version of the page which is designed to be non-AddressFamily specific, for the old version see NetworkProgrammingOld

General structure for a server setup

The various steps of setting up a server are:

  1. Creating a socket of the correct type, with socket(2)
  2. bind(2) the socket to a port (and optionally an interface)
  3. listen(2) on that port
  4. accept(2) client connections

getaddrinfo(3) will sort out the correct parameters for socket(2) and bind(2), making things fairly simple. An example below:

  • First find our what to bind to.
  1. include <sys/socket.h>
  2. include <sys/types.h>
  3. include <netdb.h>

int bind_service(char *service,int socktype) {

struct addrinfo hints; struct addrinfo *result; struct addrinfo *result_iter; int serverfd;

hints.ai_flags=AI_PASSIVE; hints.ai_family=PF_UNSPEC; /* We don't care if it's PF_INET, or PF_INET6 / hints.ai_socktype=SOCK_STREAM / 0 for any type, SOCK_STREAM for streams, SOCK_DGRAM for datagrams / hints.ai_protocol=0; / 0 for any protocol, use getprotobyname(3) to find a protocol / hints.ai_addrlen=0; hints.ai_addr=NULL; hints.ai_canonname=NULL; / Unused */ hints.ai_next=NULL;

ret=getaddrinfo(NULL,service,&hints,&result); if (ret!=0) {

fprintf(stderr,"getaddrinfo failed: %s",gai_strerror(ret)); return -1;

}

for(result_iter = result;result_iter;result_iter=result_iter->next) {

serverfd = socket(result_iter->ai_family,result_iter->ai_socktype,result_iter->ai_protocol); if (serverfd<0) {

perror("socket"); continue;

} if (bind(serverfd,result_iter->address,result_iter->addrlen)<0) {

perror("bind"); continue;

} break;

}

if (!result_iter) {

fprintf(stderr,"Unable to bind to service \"%s\"\n",service); freeaddrinfo(result); return -1;

}

freeaddrinfo(result); return serverfd;

}

void do_client(int clientfd) {

char *message = "Hello World\n"; write(clientfd,message); close(clientfd);

}

int main(int argc,char **argv) {

int serverfd;

serverfd = bind_service("hello",SOCK_STREAM);

if (serverfd<0) {

return 1;

}

if (listen(serverfd,8)<0) {

perror("listen"); return 1;

}

for (;;) {

int clientfd;

clientfd = accept(serverfd);

if (clientfd<0) {

perror("accept"); /* Note that accept tends to fail reasonably often, so don't abort the server here */

}

if (fork()==0) {

/* Client Thread */ close(serverfd); do_client(clientfd); exit(0);

} else {

/* Server Thread */ close(clientfd);

}

}

close(serverfd);

}