Path: utzoo!yunexus!geac!david From: david@geac.UUCP (David Haynes) Newsgroups: comp.unix.questions Subject: Re: What is 'sockets' ??? (A Simple Tutorial) Message-ID: <3179@geac.UUCP> Date: 26 Aug 88 12:02:32 GMT Article-I.D.: geac.3179 References: <916@altger.UUCP> <913@buengc.BU.EDU> <24549@bu-cs.BU.EDU> Reply-To: david@geac.UUCP (David Haynes) Organization: /usr/lib/news/organisation Lines: 460 In article <24549@bu-cs.BU.EDU> madd@bu-it.bu.edu (Jim Frost) writes: >In article <913@buengc.BU.EDU> bph@buengc.bu.edu (Blair P. Houghton) writes: >|In article <916@altger.UUCP> amigaeb@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 #include #include #include 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 #include #include #include 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 #include #include #include #include #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 #include #include #include #include #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 #include #include #include #include #include #include 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 #include #include #include #include #include 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}