64
CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

  • View
    230

  • Download
    3

Embed Size (px)

Citation preview

Page 1: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

CS 620 Advanced Operating Systems

Lecture 3 – UNIX IPC Programming Review

Professor Timothy Arndt

BU 331

Page 2: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

UNIX Programming Review

• UNIX manages multiple concurrent processes. Each process is represented by an entry in the

process table. A process goes through a number of states

before running to completion• Running• Asleep• Ready• Zombie

Page 3: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Process Creation

• The fork system call is used inside a C program to create another process. After the fork call, both a parent and child

process are running. The child process has a unique PID, and PPID,

but otherwise is equivalent to the parent (i.e. it is a copy of the same program).

The PID is used to distinguish the child from the parent process.

Page 4: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Process Creation

#include <stdio.h>#include <unistd.h>#include <stdlib.h>

main(){ int child_id; child_id = fork(); /* process creation */ if ( child_id == 0 ) /* child code begin */ { printf("Child says my pid = %d and my parent pid = %d\n", getpid(), getppid()); _exit(0); /* child terminates (i) */ } /* child code end */ /* remaining parent code */ if ( child_id < 0 ) { fprintf(stderr, "fork failed\n"); exit(1); } printf("Parent says child pid = %d\n", child_id);}

Page 5: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Program Execution: exec

• The child process can also run a different program than the parent by overlaying a new executable file on itself. This is done using one of the exec routines:

execl, execv, execve, etc. The execed file can either be an executable

binary file or an executable text file (e.g. a shell script).

The various exec routines vary in the type and number of arguments they take.

Page 6: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Exec Example

#include <stdio.h>#include <unistd.h>#include <string.h>#define MAXLINE 80

int main(){ char cmd[MAXLINE]; void background(char *cmd); for (;;) { printf("mysh ready%%"); /* prompt */ fgets(cmd, MAXLINE, stdin); /* read command */ if ( strcmp(cmd,"exit") == 0 ) return(0); background(cmd); /* start background job */ }}

Page 7: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Exec Example

#define WHITE "\t \n"#define MAXARG 20

void background(char *cmd){ char *argv[MAXARG]; int id, i = 0; /* to fill in argv */ argv[i++] = strtok(cmd, WHITE); while ( i < MAXARG && (argv[i++] = strtok(NULL, WHITE)) != NULL ); if ( (id = fork()) == 0) /* child executes background job */ { execv(argv[0], argv); _exit(1); /* execv failed */ } else if ( id < 0 ) { fprintf(stderr, "fork failed\n"); perror("background:"); }}

Page 8: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Synchronization of Parent and Child

After creating a child process using fork, the parent may run independently, or it may wait for the child process to terminate before proceeding further.

The wait call searches for a terminated child (in the zombie state) of the calling process.

If there are no child processes, wait returns with a value of -1

If one or more child processes are in the zombie state, wait selects an arbitrary child, frees its process table slot, stores its exit status and returns it PID

Otherwise, wait blocks until one of the child processes terminates.

Page 9: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Synchronization of Parent and Child

#include <stdio.h>#include <unistd.h>#include <sys/wait.h>

int main(){ int pid1, pid2, pid; union wait status; if ((pid1 = fork()) == 0) /* child one */ { printf("child pid=%d\n", getpid()); _exit(0); } printf("forking again\n"); if ((pid2 = fork()) == 0) /* child two */ { printf("child pid=%d\n", getpid()); _exit(1); }

Page 10: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Synchronization of Parent and Child

printf("first wait\n"); pid = wait(&status); printf("pid=%d, status=%d\n", pid, status); printf("2nd wait\n"); pid = wait(&status); printf("pid=%d, status=%d\n", pid, status); return(0);}

Page 11: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

More on Wait

• The waitpid system call can be used to search for a particular child Another system call – waitid – provides even

more flexibility.

• The ‘status’ returned can be examined more closely to get info about how the process terminated by using one of several macros WEXITSTATUS(status), WIFSIGNALED(status),

WCOREDUMP(status), WSTOPSIG(status), etc.

Page 12: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Interrupts and Signals

Signals are used in UNIX to tell a running process that some event has occurred.

After receiving a signal, a process reacts to it in a well-defined manner.

There are a number of different signals that can be sent: SIGHUP 1; SIGINT 2; SIGQUIT 3; SIGILL 4; SIGTRAP 5; SIGFPE 8; SIGKILL 9; SIGBUS 10; SIGSEGV 11; SIGSYS 12; SIGVTALRM 26; SIGPROF 27.

Page 13: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Interrupts and Signals

From the shell, a signal can be sent using the kill command with the signal to be sent along with the PID.

From a C program, the function raise sends a signal to the same process, while the function kill sends a signal to some other process.

If a signal is not currently blocked by a process, further occurrences of the signal are blocked during signal handling.

Page 14: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Interrupts and Signals

The function is suspended and the handler function for the signal is called, and finally if the handler function returns, the signal is unblocked and normal execution of the process resumes from the point of interrupt.

After receiving a signal, a process normally either exits or stops. This default behavior can be changed using the signal function, specifying a handler function for a specific signal. When that signal is received, the handler function will be invoked.

Page 15: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Signal Trapping

/* this program demonstrates the use of signal to trap * interrupts from the terminal. To terminate the program * type ^\ */#include <signal.h>#include <stdio.h>#include <unistd.h>

main(){ void cnt(int sig); signal(SIGINT, cnt); printf("Begin counting and INTERRUPTs\n"); for(;;); /* infinite loop */}

void cnt(int sig){ static int count=0; printf("Total of %d INTERRUPTS received\n", ++count);

signal(SIGINT, cnt); }

Page 16: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

IPC and Network Communication

Two processes residing either on the same computer or on different computers may need to exchange data. This is known as Inter Process Communication (IPC).

If the two processes are related by a fork, IPC can be done through the pipe mechanism (the processes are on the same machine).

If the two processes are not related, IPC can be performed using the socket mechanism.

Page 17: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Pipes

A pipe is a direct (in memory) I/O channel between processes.

It is used with the calls fork, exec, wait, and exit to make multiple processes cooperate.

To establish a pipe use the system call int pipe(int fildes[2])• This establishes a buffer and two descriptors

fildes[0] for reading the pipe and fildes[1] for writing the pipe.

• The pipe is created before the fork, so both parent and child have copies of the pipe.

Page 18: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Pipes

I/O is performed through a pipe using the read and write calls.

Read removes characters from the buffer and write deposits them.

The buffer size is usually 4096 characters. If we write a full pipe buffer, the process blocks

until more space is available in the pipe. If we read an empty buffer, the reading process

blocks unless the write end of the pipe has been closed - in this case 0 (end of file) is returned.

Page 19: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Pipes

#include <stdio.h>#include <unistd.h>#include <string.h>#include <sys/wait.h>

int main(int argc, char *argv[]){ int p[2]; int i, pid, status; char buffer[20]; pipe(p); /* setting up the pipe */ if ((pid = fork()) == 0) /* in child */ { close(p[1]); /* child closes p[1] */ while ((i = read(p[0], buffer, 6)) != 0) { buffer[i] = '\0'; /* string terminator */ printf("%d chars :%s: received by child\n", i, buffer); } _exit(0); /* child terminates */ }

Page 20: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Pipes

/* in parent */ close(p[0]); /* parent writes p[1] */ write(p[1], "Hello there,", sizeof("Hello there,")); write(p[1], " from me.", sizeof(" from me.")); close(p[1]); /* finished writing p[1] */ while (wait(&status)!=pid); /* waiting for pid */ if (status == 0) printf("child finished\n"); else printf("child failed\n"); return(0);}

Page 21: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

The dup2 Command

• The following example shows the use of the dup2 command which duplicates an existing I/O descriptor.

Page 22: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Pipes

#include <stdio.h>#include <string.h>#include <unistd.h>#include <stdlib.h>int main(int argc, char *argv[]){ int p[2]; int i,pid1,pid2, status; argv++; /* lose argv[0] */ for (i = 1; i <= argc ; i++) if (strcmp(argv[i],"%") == 0) { argv[i] = '\0'; /* break into two commands */ break; } pipe(p); /* setting up the pipe */ if ((pid1 = fork ()) == 0) /* child one */ { close(p[1]); dup2(p[0],0); /* 0 becomes a duplicate of p[0] */ close(p[0]); execv(argv[i+1], &argv[i+1]); /* this reads the pipe */

Page 23: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Pipes

_exit(1); /* bad error execl failed */ } if ((pid2 = fork ()) == 0) /* child two */ { close(p[0]); dup2(p[1],1); /* 1 becomes a duplicate of p[1] */ close(p[1]); execv(argv[0],argv); /* this writes the pipe */ _exit(1); /* bad error execv failed */ } /* parent does not use pipe */ close(p[0]); close(p[1]); while (wait(&status)!=pid2); /* waiting for pid2 */ if (status == 0) printf("child two terminated\n"); else printf("child two failed\n"); exit(0);}

Page 24: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Two-Way Pipe Connections

• In order to have two-way pipe connections between two processes, two pipes must be used. This is shown in the following example.

Page 25: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Two-Way Pipe Connections

#include <stdio.h>#include <string.h>

int readl(int fd, char s[], int size){ char *tmp = s; while (0 < --size && read(fd, tmp, 1) != 0 && *tmp++ != '\n'); *tmp = '\0'; /* string terminator */ return(tmp - s);}

int pipe_2way(char *cmd[], int piped[]){ int pid, wt[2], rd[2]; pipe(rd); /* incoming pipe: read by parent */ pipe(wt); /* outgoing pipe: write to child */ if ((pid=vfork()) == 0)

Page 26: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Two-Way Pipe Connections

{ close(wt[1]); /* in child */ dup2(wt[0],0); /* 0 identified with wt[0] */ close(wt[0]); close(rd[0]); dup2(rd[1], 1); /* 1 identified with rd[1] */ close(rd[1]); execv(cmd[0],cmd); /* execute given command */ perror("execv failed"); /* normally not reached */ _exit(1); } close(wt[0]); /* in parent */

piped[1] = wt[1]; close(rd[1]); piped[0] = rd[0]; return(0);}

Page 27: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Two-Way Pipe Connections

#define SIZE 256int main(){ int pd[2]; char *str[2]; char test_string[] = "IPC WITH TWO-WAY PIPE.\n"; char buf[SIZE]; char *tmp = buf;

str[0] = "./lowercase"; str[1] = NULL; pipe_2way(str, pd); /* write to lowercase process */ write(pd[1], test_string, strlen(test_string)); readl(pd[0], buf, SIZE); /* read from lowercase process */ printf("Received from lowercase process:\n%s", buf); return(0);}

Page 28: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Two-Way Pipe Connections

/***** The lowercase program *****/

#include <stdio.h>#include <stdlib.h>#include <ctype.h>#define BUFSIZE 1024

void lower(char *buf, int length){ while (length-- > 0) { *buf = tolower( *buf ); buf++; }}

Page 29: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Two-Way Pipe Connections

int main(int argc, char *argv[]){ char buffer[BUFSIZE]; int nc; while ((nc = read(0, buffer, BUFSIZE)) > 0) { lower(buffer,nc); nc = write(1, buffer, nc);

if (nc == -1) break; } if (nc == -1) { perror(argv[0]); exit(1); } return(0);}

Page 30: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Named Pipes

• Linux provides a similar IPC mechanism called named pipes (or FIFOs). Can be used to communicate between 2

unrelated processes• Have an entry in the (file) directory• Create using mknod (from shell or program)• Have permissions (like files)• Survive the end of a program (like files)• Must be explicitly removed (like files)

Page 31: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Sockets

Sockets are abstractions that serve as endpoints of communication within a networking domain.

The socket is the ipc mechanism’s interface to application programs. Each socket can exchange data with any other socket within the same domain (e.g. the Internet domain).

Each socket is assigned a type property. Different type sockets use different protocols. • Stream sockets support bidirectional, reliable,

sequenced flow of data Stream sockets in the Internet domain use TCP/IP.

Page 32: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Sockets

Datagram sockets provide bidirectional flow of data packets called messages • The communication channel is not sequenced, reliable, or

unduplicated • A datagram socket does not have to be connected to a peer • A message is sent to a datagram socket by specifying its

address• Datagram sockets in the Internet domain use UDP/IP.

Raw sockets give access to the underlying communications protocol• They are not intended for the general user• In the Internet domain, they give direct access to the Internet

Protocol (IP).

Page 33: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Sockets

The socket system call creates a socket of a particular type in a particular domain• The type and domain are given by constants defined

in sys/socket.h Sockets must then be given an address so that

other processes can refer to them• In Internet domain, socket address consists of

combination of host IP address and port number• Standard network services are assigned the same

port number on each host • A database file contains a list of services and port

number.

Page 34: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Sockets

grail:/users/faculty/arndt> cd /etcgrail:/etc> more services…daytime 13/tcpdaytime 13/udpqotd 17/tcp quoteqotd 17/udp quotemsp 18/tcp # message send protocolmsp 18/udp # message send protocolchargen 19/tcp ttytst sourcechargen 19/udp ttytst sourceftp-data 20/tcpftp-data 20/udp# 21 is registered to ftp, but also used by fspftp 21/tcpftp 21/udp fsp fspdssh 22/tcp # SSH Remote Login Protocolssh 22/udp # SSH Remote Login Protocoltelnet 23/tcptelnet 23/udp# 24 - private mail systemlmtp 24/tcp # LMTP Mail Deliverylmtp 24/udp # LMTP Mail Deliverysmtp 25/tcp mail…

Page 35: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Sockets

• To bind a name to socket, use the system call bind(int soc, struct sockaddr *addr, int addrlen)

• The following example illustrates the use of datagram sockets with a sender process and a receiver process.

Page 36: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Datagram Sockets

#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <sys/file.h>#include <sys/socket.h>#include <sys/un.h> /* UNIX domain header */int main(){ int soc; char buf[] = "Hello there"; const char *NAME = "./receiver_soc"; struct sockaddr_un peer; /* (1) */ int n;

peer.sun_family = AF_UNIX;strcpy(peer.sun_path, NAME);

soc = socket(AF_UNIX, SOCK_DGRAM, 0); /* (2) */

Page 37: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Datagram Sockets

if ( access(peer.sun_path, F_OK) > -1 ) /* (3) */ { n = sendto(soc, buf, strlen(buf), /* (4) */ 0, (struct sockaddr *)&peer, sizeof(peer)); if ( n < 0 ) { fprintf(stderr, "sendto failed\n"); exit(1); }

printf("Sender: %d characters sent!\n", n); /* (5) */ close(soc); /* (6) */ } return(0);}

Page 38: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Datagram Sockets

/***** File : receiver.c *****/ /***** datagram socket example: receiver process *****/ #include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <sys/socket.h>#include <sys/un.h> /* UNIX domain header */

void cleanup(int soc, char *file){ close(soc); unlink(file);}

Page 39: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Datagram Sockets

int main(){ int soc; char buf[64]; const char *NAME = "./receiver_soc2"; struct sockaddr_un self; /* (A) */ struct sockaddr_un peer; int n, len;

self.sun_family = AF_UNIX;strcpy(self.sun_path, NAME);

soc = socket(AF_UNIX, SOCK_DGRAM, 0); /* (B) */ n = bind(soc, (const struct sockaddr *)&self, sizeof(self)); if ( n < 0 ) { fprintf(stderr, "bind failed\n"); exit(1); } n = recvfrom(soc, buf, sizeof(buf), /* (D) */ 0, (struct sockaddr *)&peer, &len);

Page 40: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Datagram Sockets

if ( n < 0 ) { fprintf(stderr, "recvfrom failed\n"); cleanup(soc, self.sun_path); exit(1); }

buf[n] = '\0'; /* (E) */ printf("Datagram received = %s\n", buf); /* (F) */ cleanup(soc, self.sun_path); return(0);}

Page 41: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Datagram Sockets

• Note that we have two separate processes (we have two main functions). Both must be compiled.

• In order to run the example, both processes must be launched:receiver &sender

• The sendto and recvfrom system calls are normally used with datagram sockets.

Page 42: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Stream Sockets

A stream socket is connected with its peer to form a two-way pipe between a client and a server.• The server process listens for connection requests

and accepts connections. The server process binds a known address to a socket.

• The client process uses its socket to initiate a connection to a socket of a server process.

The client process finds the correct address of the server. Then initiates a connection to the server process.

• After connection, data communication takes place using the read and write I/O system calls.

Page 43: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Stream Sockets

The connect system call - connect(int soc, struct sockaddr *name, int namelen) - associates the client socket given by the descriptor soc to a peer socket in a server specified by *name.

The connect call is often used by client programs to connect to stream sockets of known services on the Internet.

A pair of sockets forms a virtual circuit between the client and server process.

Page 44: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Stream Sockets

A server process with a stream socket needs to take the following steps to get ready to accept a connection:• Create a socket in the appropriate domains of type

SOCK_STREAM• Construct the correct address and bind it to the

socket• Indicate a willingness to accept connection requests

by executing the listen system call.• Use the accept call to wait for a connection request

and establish a connection.

Page 45: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Stream Sockets

int listen(int soc, int n) initializes the socket for incoming requests and sets the maximum number of pending connections.

int accept(int soc, struct sockaddr *addr, int *addrlen) accepts connections on the socket on which a listen has been executed• If there are pending connections, the first is chosen

and a new socket is created with the same properties as soc

This socket is connected and a descriptor of the socket is returned.

Page 46: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Stream Sockets

The listening socket remains ready to receive connection requests.

If no connections are pending and the socket is not marked as nonblocking (using system call fcntl), accept blocks until a connection request arrives.

If the connection is marked as nonblocking and no requests are pending, accept returns an error.• The accepted socket communicates with its peer and

may not accept additional connections.

Page 47: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Stream Sockets

For connected sockets, the basic read and write system calls send and receive data:• write(soc, buffer, sizeof(buffer));• read(soc, buffer, sizeof(buffer));

Each process reads and writes its own socket, resulting in a bidirectional data flow between the connected peers. The socket I/O calls • send(soc, buffer, sizeof(buffer), opt);• recv(soc, buffer, sizeof(buffer), opt);

Can be used by stream sockets to send out-of-band data by setting opt to MSG_OOB.

Page 48: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Stream Socket Example

/***** stream socket example: server.c *****/ #include <sys/types.h>#include <sys/socket.h>#include <sys/un.h> /* UNIX domain header */#include <stdlib.h>#include <stdio.h>int main(){ int soc, ns, k; char buf[256]; struct sockaddr_un self = {AF_UNIX, "serversoc"}; struct sockaddr_un peer = {AF_UNIX}; int peer_len = sizeof(peer); /* set up listening socket soc */ soc = socket(AF_UNIX, SOCK_STREAM, 0); /* (1) */ if (soc < 0) { perror("server:socket"); exit(1); }

Page 49: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Stream Socket Example

if (bind(soc, (struct sockaddr *)&self, sizeof(self)) == -1) { perror("server:bind"); close(soc); exit(1); } listen(soc, 1); /* accept connection request */ ns = accept(soc, (struct sockaddr *)&peer,

&peer_len); if (ns < 0) { perror("server:accept"); close(soc); unlink(self.sun_path); exit(1); } /* data transfer on connected socket ns */ k = read(ns, buf, sizeof(buf)); printf("SERVER RECEIVED: %s\n", buf); write(ns, buf, k); close(ns); close(soc); unlink(self.sun_path);

return(0); }

Page 50: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Stream Socket Example

/***** File : client.c *****/ /***** socket example: receiver process *****/#include <stdio.h>#include <stdlib.h>#include <sys/types.h> #include <sys/socket.h>#include <sys/un.h> /* UNIX domain header */int main(){ int soc; char buf[256]; struct sockaddr_un self={AF_UNIX, "clientsoc"}; struct sockaddr_un peer={AF_UNIX, "serversoc"};

soc = socket(AF_UNIX, SOCK_STREAM, 0);bind(soc, (struct sockaddr *)&self, sizeof(self));/* request connection to serversoc */

if (connect(soc, (struct sockaddr *)&peer, sizeof(peer)) == -1)

{ perror("client:connect"); close(soc);

Page 51: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Stream Socket Example

unlink(self.sun_path); exit(1);}write(soc, "hello from client", 18);read(soc, buf, sizeof(buf));printf("SERVER ECHOED: %s\n", buf);close(soc);unlink(self.sun_path);return(0);

}/*** end of client.c ***/

Page 52: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Stream Socket Example

• Note that it is not strictly necessary to bind an explicit address for a client process

• The close system call closes both halves of a socket

• To close the read and write halves independently, the shutdown system call can be used

Page 53: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Network Databases and Address Mapping

The previous example programs involved sockets with UNIX domain addresses - a simple name

For Internet domain sockets, the socket address involves both the numeric IP address of a host as well as a port number for a particular server

The DNS, a set of database files, and a collection of library functions combine to help construct required Internet socket addresses in application programs

Page 54: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Network Databases and Address Mapping

Some of the important files for name resolution are:• /etc/resolv.conf - the configuration file for the DNS

resolver. Lists name servers for the local domain.• /etc/named.boot - the DNS name server boot file.

Needed only on a host that runs a name server. Gives the locations of root name servers, e-mail exchange information, etc.

• /etc/services - contains information regarding well known Internet services.

• /etc/protocols - contains information regarding known Internet protocols.

Page 55: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Network Databases and Address Mapping

grail:/etc> more /etc/resolv.confsearch cba.csuohio.edu csuohio.edunameserver 137.148.49.12nameserver 137.148.49.11grail:/etc> more named.boot;; type domain source file;directory /etc/named.data ; running directory for namedprimary 0.0.127.IN-ADDR.ARPA db.127.0.0primary cba.csuohio.edu db.cbaprimary 20.148.137.IN-ADDR.ARPA db.137.148.20secondary csuohio.edu 137.148.5.2 db.137.148cache . db.cacheprimary 21.148.137.IN-ADDR.ARPA db.137.148.21

Page 56: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Network Databases and Address Mapping

grail:/etc> more /etc/protocols# /etc/protocols:# $Id: protocols,v 1.6 2007/05/23 15:55:03 pknirsch Exp $## Internet (IP) protocols## from: @(#)protocols 5.1 (Berkeley) 4/17/89## Updated for NetBSD based on RFC 1340, Assigned Numbers (July 1992).## See also http://www.iana.org/assignments/protocol-numbers

ip 0 IP # internet protocol, pseudo protocol number

hopopt 0 HOPOPT # hop-by-hop options for ipv6icmp 1 ICMP # internet control message protocoligmp 2 IGMP # internet group management protocolggp 3 GGP # gateway-gateway protocolipencap 4 IP-ENCAP # IP encapsulated in IP (officially

``IP'’)

Page 57: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Network Databases and Address Mapping

st 5 ST # ST datagram modetcp 6 TCP # transmission control protocolcbt 7 CBT # CBT, Tony Ballardie

<[email protected]>egp 8 EGP # exterior gateway protocoligp 9 IGP # any private interior gateway (Cisco: for

IGRP)bbn-rcc 10 BBN-RCC-MON # BBN RCC Monitoringnvp 11 NVP-II

# Network Voice Protocolpup 12 PUP # PARC universal packet protocolargus 13 ARGUS # ARGUSemcon 14 EMCON # EMCONxnet 15 XNET # Cross Net Debuggerchaos 16 CHAOS # Chaosudp 17 UDP # user datagram protocolmux 18 MUX # Multiplexing protocoldcn 19 DCN-MEAS # DCN Measurement Subsystemshmp 20 HMP # host monitoring protocolprm 21 PRM # packet radio measurement protocol…

Page 58: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Network Databases and Address Mapping

The name resolver can be used in an application program by a set of standard routines.• The library function gethostbyname:#include <netdb.h>hostent *gethostbyname(char *host)

• given a host name (a string) returns a pointer to a hostent structure

struct hostent{ char *h_name; /* official name of the host */ char **h_aliases; /* aliases */

int h_addrtype; /* address type: AF_INET */ int h_length; /* length of address */ char **h_addr_list; /* IP addresses */

};

Page 59: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Network Databases and Address Mapping

The IP address can then be copied into the sin_addr field of a sockaddr_in structure for a target socket.

To determine the port number for standard network services use:

struct servent *getservbyname(char *service, char *proto)

struct servent { char *s_name; /* official name of service */ char **s_aliases; /* alias list */

int s_port; /* port number: network byte order */char *s_proto; /* protocol used */ };

Page 60: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Internet Stream Socket Example

/***** inetserver.c *****/ #include <stdlib.h> /* for getenv */#include <stdio.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h> /* Internet domain header */#include <strings.h>#define SERVER_PORT 59154struct sockaddr_in self = {AF_INET};int main(){ int soc, ns, k; char buf[256]; struct sockaddr_in peer = {AF_INET}; int peer_len = sizeof(peer); char *host; /* set up listening socket soc */

Page 61: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Internet Stream Socket Example

soc = socket(AF_INET, SOCK_STREAM, 0); if (soc < 0) { perror("server:socket"); exit(1); } bzero(&self, sizeof(self)); self.sin_family = AF_INET; self.sin_addr.s_addr = htonl(INADDR_ANY); self.sin_port = htons(SERVER_PORT); if (bind(soc, (struct sockaddr *)&self,

sizeof(self)) == -1) { perror("server:bind"); close(soc); exit(1); } listen(soc, 1); /* accept connection request */ ns = accept(soc, (struct sockaddr *)&peer, &peer_len); if (ns < 0) { perror("server:accept"); close(soc); exit(1); } /* data transfer on connected socket ns */

Page 62: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Internet Stream Socket Example

k = read(ns, buf, sizeof(buf)); host = getenv("HOST"); printf("SERVER ON %s RECEIVED: %s\n”, host, buf); write(ns, buf, k); close(ns); close(soc); return(0);}/***** inetclient.c *****/ #include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h> /* Internet domain header */#include <netdb.h>

Page 63: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Internet Stream Socket Example

#include <strings.h>#define SERVER_PORT 59154struct sockaddr_in peer = {AF_INET};

int main(int argc, char* argv[]){ int soc; char buf[256]; struct hostent *hp; if ( argc != 2 ) { fprintf(stderr, "Usage: %s hostname\n", argv[0]); exit(1); }/* fill in peer address */ hp = gethostbyname(argv[1]); if ( hp == NULL ) { fprintf(stderr, "%s: %s unknow host\n", argv[0], argv[1]);

Page 64: CS 620 Advanced Operating Systems Lecture 3 – UNIX IPC Programming Review Professor Timothy Arndt BU 331

Internet Stream Socket Example

exit(1); }

bzero(&peer, sizeof(peer)); peer.sin_family = AF_INET; peer.sin_addr.s_addr = htonl(INADDR_ANY); peer.sin_port = htons(SERVER_PORT); bcopy(hp->h_addr_list[0], (char*)&peer.sin_addr, hp->h_length);/* create socket */ soc = socket(AF_INET, SOCK_STREAM, 0);/* request connection to server */ if (connect(soc, (struct sockaddr *)&peer,

sizeof(peer)) == -1) { perror("client:connect"); close(soc); exit(1); } write(soc, "Hello Internet", 15); read(soc, buf, sizeof(buf)); printf("SERVER ECHOED: %s\n", buf); close(soc); return(0);}