What is 'sockets' ??? (A Simple Tutorial)

David Haynes david at geac.UUCP
Fri Aug 26 22:02:32 AEST 1988


In article <24549 at bu-cs.BU.EDU> madd at bu-it.bu.edu (Jim Frost) writes:
>In article <913 at buengc.BU.EDU> bph at buengc.bu.edu (Blair P. Houghton) writes:
>|In article <916 at altger.UUCP> amigaeb at altger.UUCP (Ronny Hansen) writes:
>|>I am trying to learn about socket's, but I cant find anything
>|>to learn from. No books. No magazines. No nothing.
>|
>|Look for "A 4.2BSD Interprocess Communication Primer" [...]
>|Pure literary review:  it's one of the hardest things to read I've ever
>|read.  It ain't the material, either.  It's just a style problem.
>|Well, noone said computerz was e-z...
>
>I found that it was nice for info once I understood what was happening
>but it's not the kind of thing to unleash on a beginner.  Here's my
>quick primer.
>
[Jim's Primer Deleted]

I have found the following document to be of use to the folks here.
It is formatted for LaTeX, but can be quickly modified to, say, nroff.

-david-

---------------------( cut here )---------------------------
\documentstyle[fullpage,11pt]{article}
\title{A Cookbook Approach to\\ Interprocess Communication}
\author{David Haynes}
\date{November 19, 1987}
\begin{document}
\maketitle
\newpage
\tableofcontents
\newpage
\section{Introduction}
In the following document samples of structured code  are presented as
a cookbook approach for the creation of programs utilizing interprocess
communication of the Berkeley socket variety. There are three types of
interprocess communication presented in this paper for completeness.
\newpage
\section{UNIX Domain Communication}
\subsection{Client}
\begin{verbatim}
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>

main()
{
        char *msg, ack[2];
        int i, sd;
        struct sockaddr_un sin;
/*
 *      set up a unix domain socket
 */
        strcpy(sin.sun_path, "./socket");
        if((sd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
                perror("socket");
                exit(1);
        }
/*
 *      connect to the UNIX socket ./socket
 */
        if(connect(sd, 0, 0) == -1) {
                perror("connect");
                exit(1);
        }
/*
 *      send a message to the server
 */
        if(send(sd, msg, sizeof(msg), 0) == -1) {
                perror("send");
                exit(1);
        }
/*
 *      wait for a message to come back from the server
 */
        if(recv(sd, ack, 2, 0) == -1) {
                perror("recv");
                exit(1);
        }
/*
 *      close the socket connection
 */
        close(sd);
}
\end{verbatim}
\newpage
\subsection{Server}
\begin{verbatim}
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>

main()
{
        char *msg, ack[2];
        register int i;
        int sd, sd_current, count;
        struct sockaddr_un sin;
/*
 *      get a UNIX domain socket
 */
        strcpy(sin.sun_path, "./socket");
        if((sd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
                perror("socket");
                exit(1);
        }
/*
 *      bind the socket to the socket name ./socket
 */
        if(bind(sd, &sin, sizeof(sin)) == -1) {
                perror("bind");
                exit(1);
        }
/*
 *      show that we are willing to listen
 */
        if(listen(sd, 5) == -1) {
                perror("listen");
                exit(1);
        }
/*
 *      wait for someone to talk to us
 */
        if((sd_current = accept(sd, 0, 0)) == -1) {
                perror("accept");
                exit(1);
        }
/*
 *      get a message from the client
 */
        if(recv(sd_current, msg, MSG_SIZE, 0) == -1) {
                perror("recv");
                exit(1);
        }
/*
 *      acknowledge the message
 */
        if(send(sd_current, ack, 2, 0) == -1) {
                perror("send");
                exit(1);
        }
/*
 *      close it up
 */
        close(sd_current);
        close(s);
}
\end{verbatim}
\newpage
\section{Internet Domain Communication}
\subsection{Client}
\begin{verbatim}
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

#define PORT        0x1234
#define HOST        "fileserver"

main()
{
        char *msg, ack[2];
        int i, sd;
        struct sockaddr_in sin;
        struct sockaddr_in pin;
        struct hostent *hp;
/*
 *      go find out about the desired host machine
 */
        if((hp = gethostbyname(HOST)) == 0) {
                perror("gethostbyname");
                exit(1);
        }
/*
 *      fill in the socket structure with host information
 */
        memset(&pin, 0, sizeof(pin));
        pin.sin_family = AF_INET;
        pin.sin_addr.s_addr = ((struct in_addr *)(hp->h_addr))->s_addr;
        pin.sin_port = htons(PORT);
/*
 *      grab an internet domain socket
 */
        if((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
                perror("socket");
                exit(1);
        }
/*
 *      connect to PORT on HOST
 */
        if(connect(sd, &pin, sizeof(pin)) == -1) {
                perror("connect");
                exit(1);
        }
/*
 *      send a message to the server PORT on machine HOST
 */
        if(send(sd, msg, sizeof(msg), 0) == -1) {
                perror("send");
                exit(1);
        }
/*
 *      wait for an acknowledgement handshake
 */
        if(recv(sd, ack, 2, 0) == -1) {
                perror("recv");
                exit(1);
        }
/*
 *      shut it down
 */
        if(shutdown(sd, 2) == -1) {
                perror("shutdown");
                exit(1);
        }
        close(sd);
}
\end{verbatim}
\newpage
\subsection{Server}
\begin{verbatim}
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

#define PORT 0x1234

main()
{
        char *msg, ack[2];
        register int i;
        int sd, count, cc, fromlen, tolen;
        int addrlen;
        struct sockaddr_in sin;
        struct sockaddr_in pin;
/*
 *      get an internet domain socket
 */
        if((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
                perror("socket");
                exit(1);
        }
/*
 *      complete the socket structure
 */
        memset(&sin, 0, sizeof(sin));
        sin.sin_family = AF_INET;
        sin.sin_addr.s_addr = INADDR_ANY;
        sin.sin_port = htons(PORT);
/*
 *      bind the socket to the port number
 */
        if(bind(sd, &sin, sizeof(sin)) == -1) {
                perror("bind");
                exit(1);
        }
/*
 *      show that we are willing to listen
 */
        if(listen(sd, 5) == -1) {
                perror("listen");
                exit(1);
        }
/*
 *      wait for someone to talk to us
 */
        if((sd_current = accept(sd, &pin, &addrlen)) == -1) {
                perror("accept");
                exit(1);
        }
/*
 *      get a message from the client
 */
        if(recv(sd_current, msg, conf.size, 0) == -1) {
                perror("recv");
                exit(1);
        }
/*
 *      send an acknowledgement message
 */
        if(send(sd_current, ack, 2, 0) == -1) {
                perror("send");
                exit(1);
        }
/*
 *      close it up
 */
        close(sd_current);
        close(sd);
}
\end{verbatim}
\newpage
\section{UDP Domain Communication}
\subsection{Client}
\begin{verbatim}
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/errno.h>
#include <signal.h>
#include <netinet/in.h>
#include <stdio.h>
#include <netdb.h>

void t_nop() {signal(SIGALRM, t_nop);}

main()
{
        char buf[512], ack[2];
        int s, retry;
        extern int errno;                /* error type */
        struct hostent *hp;                /* our port descriptor */
        struct servent *sp;                /* server's port descriptor */
        struct sockaddr_in myaddr;        /* our internet descriptor */
        struct sockaddr_in svaddr;        /* server's internet descriptor */
/*
 *      clear and initialize the socket descriptors
 */
        memset((char *)&myaddr, 0, sizeof(struct sockaddr_in));
        memset((char *)&svaddr, 0, sizeof(struct sockaddr_in));
        svaddr.sin_family = AF_INET;
        hp = gethostbyname("fileserver");
        if(hp == NULL) {
                fprintf(stderr, "fileserver not found in /etc/hosts\n");
                exit(1);
        }
        svaddr.sin_addr.s_addr = ((struct in_addr *)(hp->h_addr))->s_addr;
        sp = getservbyname("example", "udp");
        if(sp == NULL) {
                fprintf(stderr, "example not found in /etc/services\n");
                exit(1);
        }
        svaddr.sin_port = sp->s_port;
/*
 *      create the socket
 */
        s = socket(AF_INET, SOCK_DGRAM, 0);
        if(s == -1) {
                perror("socket");
                exit(1);
        }
/*
 *      add some home truths about ourselves
 */
        myaddr.sin_family = AF_INET;
        myaddr.sin_port = 0;
        myaddr.sin_addr.s_addr = INADDR_ANY;
/*
 *      bind the socket to our port
 */
        if(bind(s, &myaddr, sizeof(struct sockaddr_in)) == -1) {
                perror("bind");
                exit(1);
        }
/*
 *      attempt to send a message to the server
 */
                signal(SIGALRM, t_nop);
                retry = 5;
again:        a        if(sendto(s, &obs, sizeof(OBS), 0,
                        &svaddr, sizeof(struct sockaddr_in)) == -1) {
                        perror("sendto");
                        exit(1);
                }
                alarm(5);
                if(recv(s, ack, 2, 0) == -1) {
                        if(errno == EINTR) {
                                if(--retry) {
                                        goto again;
                                }
                                else {
                                        perror("recv");
                                        exit(1);
                                }
                        }
                        else {
                                perror("recv");
                                exit(1);
                        }
                }
                alarm(0);
        }
}
\end{verbatim}
\subsection{Server}
\begin{verbatim}
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <errno.h>

main()
{
        char *msg;                        /* message pointer */
        char ack[2];                        /* ack buffer */
        int s, cc, addrlen;
        struct sockaddr_in myaddr;        /* my internet location */
        struct sockaddr_in claddr;        /* the client's internet location */
        struct servent *sp;                /* the port map for my service */
/*
 *      clear and initialize the socket decriptors
 */
        memset((char *)&myaddr, 0, sizeof(struct sockaddr_in));
        memset((char *)&claddr, 0, sizeof(struct sockaddr_in));
        myaddr.sin_family = AF_INET;
        myaddr.sin_addr.s_addr = INADDR_ANY;
        sp = getservbyname("example", "udp");
        if(sp == NULL) {
                printf("Can not find example in /etc/services\n");
                exit(1);
        }
        myaddr.sin_port = sp->s_port;
/*
 *      grab an internet socket descriptor
 */
        if((s = socket(AF_INET, SOCK_DGRAM, 0)) == ERROR) {
                perror("socket");
                exit(1);
        }
/*
 *      bind the socket to our port description as specified above
 */
        if(bind(s, &myaddr, sizeof(struct sockaddr_in)) == ERROR) {
                perror("bind");
                exit(1);
        }
/*
 *      wait for a message to arrive
 */
        errno = 0;  /* no errors at this point */
        addrlen = sizeof(struct sockaddr_in);
/*
 *      get the message which is being sent
 */
        cc = recvfrom(s, &msg, sizeof(msg), 0, &claddr, &addrlen);
        if(cc == -1) {
                perror("recv");
                exit(1);
        }
/*
 *      send an acknowledgement message
 */
        if(sendto(s, ack, 2, 0, &claddr, addrlen) == -1) {
                perror("sendto");
                exit(1);
        }
/*
 *      close it up
 */
        close(s);
}
\end{verbatim}
\end{document}



More information about the Comp.unix.questions mailing list