1 제 12 제 제제제제 제제제 제제
1
제 12 장 프로세스 사이의 통신
2
Objectives
describe how pipes are used for IPC
define the two kinds of pipes
use the system calls used with pipes
network programming with socket system call
3
IPC using Pipes
IPC using regular files unrelated processes can share fixed size life-time lack of synchronization
IPC using pipes for transmitting data between related processes unidirectional communication can transmit an unlimited amount of data automatic synchronization on open()
4
IPC using Pipes
data transmitting data is written into pipes using write() system
call data is read from a pipe using read() system
call automatic blocking when full or empty
types of pipes (unnamed) pipes named pipes
5
Example
%who | sort
pipewho sort
write pointer ofanother process
read pointer of one process
6
System Calls
int pipe(int fd[ ])
a process
fd[1] fd[0]
pipewriteread
7
System Calls
전형적인 사용법1) a process creates a pipe2) fork child process3) the writer closes its read pipe descriptor, and
the reader closes its write pipe descriptor4) transmitting data via pipe using write() and read() system call5) each process closes its active pipe descriptor
8
Pipe after fork
fd[1]Pipe
fd[0] fd[0]fd[1]
Parent Child
9
Sending messages from child to parent
#include <stdio.h>#define READ 0#define WRITE 1char* phrase = “Stuff this in your pipe and smoke it”;main( ) {
int fd[2], bytesRead;char message[100];pipe(fd); if (fork() ==0) {
close(fd[READ]);write(fd[WRITE], phrase, strlen(phrase)+1);close(fd[WRITE]);
} else {
close(fd[WRITE]);bytesRead = read(fd[READ], message, 100);printf(“Read %d bytes: %s\n”, bytesRead,message);close(fd[READ]);
}}
10
Example#include <stdio.h>#define READ 0#define WRITE 1main(argc, argv ) int argc; char* argv[];{
int fd[2];pipe(fd); if (fork() ==0) { close(fd[READ]); dup2(fd[WRITE],1); close(fd[WRITE]); execlp(argv[1], argv[1], NULL); perror(“Connect”); }
else {close(fd[WRITE]);dup2(fd[READ],0);close(fd[READ]);execlp(argv[2], argv[2], NULL);perror(“Connect”);
}}
11
Named pipes
Why named pipes ? they have a name that exists in the file system they may be used by unrelated processes they exist until explicitly deleted
How to create named pipes ? by using the UNIX mknod commond with the p option
$mknod myPipe p$chmod ug+rw myPipe$ls -lg myPipe
by using the mknod() system call
int mknod(char* path, int mode, int dev)
return 0 if successful, -1 otherwise
12
How to communicate via pipes ?
Writer process should open a named pipe for write-only write data using write() system call
Reader process should open a named pipe for read-only read data using read() system call
13
Example:Reader
#include <stdio.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/file.h>main( ) {
int fd;char str[100];unlink(“aPipe”);mknod(“aPipe”, S_IFIFO, 0);chmod(“aPipe”, 0660);fd = open(“aPipe”, O_RDONLY);
while (readLine(fd, str))printf(“%s\n”, str);
close(fd)}
14
Example:Reader
readLine(fd, str)int fd; char *str;{ int n;
do {n = read(fd, str, 1);
} while (n>0 && *str++ != NULL);return (n>0);
}
15
Example:Writer
#include <stdio.h>#include <sysfile.h>main( ) {
int fd, messageLen, i;char message[100];
sprintf(message, “Hello from PID %d”, getpid());messageLen= strlen(message)+1;do { fd = open(“aPipe”, O_WRONLY); if (fd == -1) sleep(1);} while(fd == -1);for (i =1; i<= 3; i++) {
write(fd, message, messageLen);sleep(3);
}close(fd);
}
16
Sockets
Socket bidirectional connection process communication based on client-server model
AF_UNIX socket an interprocess communication mechanism between
processes on the same UNIX machine
AF_INET socket an interprocess communication mechanism between
processes across network
17
The socket connection
Server
Server
Server
Client
Client
1. Sever creates a named socket
2. Client creates an unnamedsocket and request a connection
3. Server makes a connection.Server retains original named socket
18
Client-Server Model
Server – Server creates a named socket
using socket()
– Server makes a pending queue using listen()
– Server accept() from a client connection()
– When a socket isconnected the server usually fork() a
child process to converse with the client
Client– Client creates an unnamed
socket using socket()
– Client requests a connection using connect()
– Client makes a connection when server accept( ) it.
19
Creating a Socket
소켓 만들기 int socket(int domain, int type, int protocol)
domain AF_UNIX (the clients and server must be in the same machine) AF_INET(the and server may be anywhere on the Internet)
type SOCK_STREAM
protocol DEFAULT _PROTOCOL
ExampleserverFd = socket(AF_UNIX, SOCK_STREAM, DEFAULT _PROTOCOL);
20
Naming a Socket
소켓에 이름 ( 주소 ) 주기 int bind(int fd, struct sockaddr* address, int
addressLen) bind the unnamed socket with fd to a name in address address is a pointer to
struct sockaddr_un sun_family = AF_UNIX sun_path = name of the socket
struct sockaddr_in sin_family = AF_INET sin_port = the port number of Internet socket sin_addr = 32-bit IP address
sin_zero = leave empty addressLen = length of address structure
21
Example
serverUNIXAddress.sun_family = AF_UNIX;strcpy(serverUNIXAddress.sun_path, “recipe”);unlink(“recipe”);bind(serverFd, serverSockAddrPtr, serverLen);
22
Creating a Socket Queue
소켓 큐 생성 specify the maximum number of pending
connections on a socket int listen(int fd, int queueLength) example
listen(serverFd, 5);
23
Making the Connection
소켓에 연결 요청 int connect(int fd, struct sockaddr* address,
int addressLen) attempts to connect to a server socket whose
address is in a structure pointed to by address If successful, fd may be used to communicate with
the server’s socket
24
Accepting a Client
소켓 연결 요청 수락 int accept(int fd, struct sockaddr* address, int*
addressLen)
(1) listen to the named server socket referenced by fd
(2) wait until a client connection request is received(3) creates an unnamed socket with the same attributes as the original server socket, and connects it to the client’s socket.(4) When a connection is made, address is set to the address of the client socket and addressLen is set to the actual size(5) return a new file descriptor
25
Chef Server-Cook Client
%chef &
%cook
spam, spam, spam, spam,
spam, and spam
%cook
spam, spam, spam, spam,
spam, and spam
26
Example : Chef Server(1/3)
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#define DEFAULT_PROTOCOL 0
main ( ) {
int serverFd, clientFd, serverLen, clientLen;
struct sockaddr_un serverUNIXAddress;
struct sockaddr_un clientUNIXAddress;
struct sockaddr* serverSockAddrPtr;
struct sockaddr* clientSockAddrPtr;
signal(SIGCHLD, SIG_IGN);
27
Example : Chef Server(2/3)
serverSockAddrPtr= (struct sockaddr*) &serverUNIXAddress;
serveLen = sizeof(serverUNIXAddress);clientSockAddrPtr = (struct sockaddr*)
&clientUNIXAddress;clientLen = sizeof(clientUNIXAddress);
serverFd = socket(AF_UNIX, SOCK_STREAM,DEFAULT_PROTOCOL);
serverUNIXAddress.sun_family = AF_UNIX;strcpy(serverUNIXAddress.sun_path, “receipe”);unlink(“receipe”);
bind(serverFd, serverSockAddrPtr, serverLen);listen(serverFd, 5);
28
Example:Chef Server(3/3)
while (1) {clientFd = accept(serverFd, clientSockAddrPtr, &clientLen);if (fork ( ) == 0) {
writeRecipe(clientFd);close(clientFd);exit (0);
} else close(clientFd);}}writeRecipe(fd)int fd;{
static char* line1 =“spam, spam, spam, spam,”;static char* line2 = “spam and spam.”;write(fd, line1, strlen(line1)+1);write(fd, line2, strlen(line2)+1);
}
29
Example:Cook Client(1/3)
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#define DEFAULT_PROTOCOL 0
main ( ) {
int clientFd, serverLen, result;
struct sockaddr_un serverUNIXAddress;
struct sockaddr* serverSockAddrPtr;
serverSockAddrPtr= (struct sockaddr*)
&serverUNIXAddress;
serverLen = sizeof(serverUNIXAddress);
30
Example:Cook Client(2/3)
clientFd = socket(AF_UNIX, SOCK_STREAM, DEFAULT_PROTOCOL);
serverUNIXAddress.sun_family = AF_UNIX;
strcpy(serverUNIXAddress.sun_path, “receipe”);
do {result = connect(clientFd, serverSockAddrPtr, serverLen);
if (result == -1) sleep(1);
} while (result == -1);
readRecipe(clientFd);
close(clientFd);
exit(0) }
31
Example:Client(3/3)
readRecipe(fd);int fd;{
char str[200];while (readLine(fd, str))
printf(“%s\n”, str);}readLine(fd, str)int fd;char* str;{
int n;do {
n = read(fd, str, 1);} while(n>0 && *str++ != NULL);return(n > 0);
}
32
Internet Sockets
A client for Internet Time Listing Internet socket is specified by two values:
a 32-bit IP addressa 16-bit port number, which specifies a particular port
on the hostport number 13 is used to echo the host’s time
33
Internet Sockets
A client for Internet Time Listing Internet socket address structure
struct sockaddr_insin_family = AF_INET sin_port = 16bit port number of the Internet
socketsin_addr = 32-bit IP address ,
which is a structure of type in_addr sin_zero = leave empty
34
Example:Internet Time Listing
% inettime
Host name (q= quit, s= self): s
Self host name is cs
Internet Address= 203.252.195.1
The time on the target port is …
Host name (q= quit, s= self): monkey
Internet Address= 203.252.195.246
The time on the target port is …
Host name (q= quit, s= self): 203.252.195.247
The time on the target port is …
35
Client:Internet Time Listing(1/4)
#include <stdio.h>
#include <signal.h>
#include <ctypes.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#define DAYTIME_PORT 13
#define DEFAULT_PROTOCOL 0
main ( ) {
int clientFd, serverLen, result;
struct sockaddr_in serverINETAddress;
struct sockaddr* serverSockAddrPtr;
unsigned long inetAddress;
36
Client:Internet Time Listing(2/4)
serverSockAddrPtr= (struct sockaddr*) &serverINETAddress;
serverLen = sizeof(serverINETAddress);
while (1) {
inetAddress = promptForINETAddress( );
if (inetAddress == 0)
break;
bzero((char*)&serverINETAddress,
sizeof(serverINETAddress));
serverINETAddress.sin_family = AF_INET;
serverINETAddress.sin_addr.s_addr = inetAddress;
serverINETAddress.sin_port = htons(DAYTIME_PORT);
clientFd = socket(AF_INET, SOCK_STREAM, DEFAULT_PROTOCOL);
37
Client:Internet Time Listing(3/4)
do { result = connect(clientFd, serverSockAddrPtr, serverLen); if (result == -1) sleep(1);} while (result == -1);readTime(clientFd);close(clientFd);}
exit(0);}
38
Client:Internet Time Listing(4/4)
readTime(fd)int fd;{ char str[200];
printf(“The time on the target port is”);while (readLine(fd, str))
printf(“%s\n”, str);}
readLine(fd, str)int fd; char* str;{ int n;
do {n = read(fd, str, 1);
} while (n > 0 && *str++ != ‘\n’);return(n > 0);
}
39
promptForINETAddress
unsigned long promptForINETAddress(){
char hostName[100];unsigned long inetAddress;do {printf(“Host name (q=quit, s =self):”);
scanf(“%s”, hostName);if (strcmp(hostName, “q”) == 0) return(0);inetAddress = nameToAddr(hostName);if (inetAddress == 0)
printf(“Host name not found\n”);} while(inetAddress == 0);return(inetAddress);
}
40
nameToAddr
unsigned long nameToAddr(name)char* name;{
char hostName[100];struct hostent* hostStruct;struct in_addr* hostNode;
if(isdigit(name[0])) return(inet_addr(name));if (strcmp(name, “s”) == 0) {
gethostname(hostName, 100); printf(“Self host name is %s\n”,hostName);} else strcpy(hostName, name);hostStruct = gethostbyname(hostName);if (hostStruct == NULL) return(0);hostNode = (struct in_addr*) hostStruct->h_addr;printf(“Internet Address = %s\n”,inet_ntoa(*hostNode));return(hostNode->s_addr);
}
41
Miscellaneous system calls
unsigned long inet_addr(char* string) returns the 32-bit IP address that corresponds to the
A.B.C.D formt string
int gethostname(char* name, int nameLen) sets the character array name, of length nameLen to a
null-terminated string equal to the local host’s name
42
Miscellaneous system calls
struct hostent* gethostbyname(char* name) searches the “/etc/hosts” file and returns a
pointer to a hostent structure that describes the file entry associated with the string name
char* inet_ntoa(struct in_addr address) returns a pointer to a string that describes
address in the format A.B.C.D.
43
Internet Server(1/3)
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#define DEFAULT_PROTOCOL 0
main ( ) {
int serverFd, clientFd, serverLen, clientLen;
struct sockaddr_in serverINETAddress;
struct sockaddr_in clientINETAddress;
struct sockaddr* serverSockAddrPtr;
struct sockaddr* clientSockAddrPtr;
44
Internet Server(2/3)
int port = 13;
serverFd = socket(AF_INET, SOCK_STREAM, DEFAULT_PROTOCOL);
serverLen = sizeof(serverINETAddress);
bzero((char*) &serverINETAddress, serverLen);
ServerINETAddress.sin_family = AF_INET;
serverINETAddress.sin_addr.s_addr = htonl(INADDR_ANY);
serverINETAddress.sin_port = htons(port);
serverSockAddrPtr = (struct sockaddr*) &serverINETAddress;
bind(serverFd, serverSockAddrPtr, serverLen);
listen(serverFd, 5);
clientLen = sizeof(clientINETAddress);
clientSockAddrPtr = (struct sockaddr*) clientINETAddress
45
Internet Server(3/3)
while (1) {clientFd = accept(serverFd, clientSockAddrPtr, &clientLen);if (fork ( ) == 0) {
service(clientFd);close(clientFd);exit (0);
} else close(clientFd);}}