1. describe how pipes are used for IPC define the two kinds of pipes network programming with socket...
-
Upload
juliet-harper -
Category
Documents
-
view
214 -
download
0
Transcript of 1. describe how pipes are used for IPC define the two kinds of pipes network programming with socket...
1
describe how pipes are used for IPC
define the two kinds of pipes
network programming with socket
2
IPC using regular files unrelated processes can share fixed size life-time lack of synchronization
IPC using pipes for transmitting data between related processes can transmit an unlimited amount of data automatic synchronization on open()
3
© 숙대 창병모 4
In a UNIX shell, the pipe symbol | (the vertical bar)
In a shell, UNIX pipes look like: $ ls -alg | more $ command 1 | command 2 the standard output of command 1 becomes the
standard input of command2
We can have longer pipes: $ pic paper.ms | tbl | eqn | ditroff -ms
Data transmitting data is written into pipes using the write( ) system call data is read from a pipe using the read( ) system call automatic blocking when full or empty
Types of pipes (unnamed) pipes named pipes
© 숙대 창병모 5
% who | sort
6
pipewho sort
write pointer ofanother process
read pointer of one process
© 숙대 창병모 7
two file descriptors fd[0] : read file descriptor for the pipe fd[1] : write file descriptor for the pipe
Anything that is written on fd[1] may be read by fd[0] This is of no use in a single process. A method of communication between processes. A way to communicate with parent-child processes.
#include <unistd.h>
int pipe(int fd[2]) Returns: 0 if OK, -1 on error
© 숙대 창병모 8
파이프
커널
fd[0] fd[1]
프로세스
© 숙대 창병모
파이프 커널
fd[0] fd[1]
부모 프로세스
fd[0] fd[1]
자식 프로세스
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()5) each process closes its active pipe descriptor
10
© 숙대 창병모
파이프 커널
fd[0] fd[1]
부모 프로세스
fd[0] fd[1]
자식 프로세스
parent child: parent closes fd[0] child closes fd[1]
© 숙대 창병모
파이프 커널
fd[0] fd[1]
부모 프로세스
fd[0] fd[1]
자식 프로세스
parent child: parent closes fd[1] child closes fd[0]
© 숙대 창병모 13
Read from a pipe with write end closed returns 0 to indicate EOF
Write to a pipe with read end closed SIGPIPE generated, write() returns error (errno == EPIPE)
Atomic write A write of PIPE_BUF (kernel’s pipe buffer size) bytes
or less will not be interleaved with the writes from other processes
#include <unistd.h> /* pipe1.c */#define MAXLINE 100
int main(void) { int n, fd[2]; int pid; char line[MAXLINE];
if (pipe(fd) < 0) perror("pipe error");
if ( (pid = fork()) < 0) perror("fork error");
else if (pid > 0) { /* parent */ close(fd[0]); write(fd[1], "hello world\n", 12); } else { /* child */ close(fd[1]); n = read(fd[0], line, MAXLINE); write(STDOUT_FILENO, line, n); } exit(0);}
© 숙대 창병모 14
© 숙대 창병모 16
Pipes can be used only between related processes
FIFOs are "named pipes" can be used between unrelated processes
A type of file stat.st_mode == FIFO Test with S_ISFIFO macro
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
17
© 숙대 창병모 18
Creating FIFOs is similar to creating a file pathname : filename mode: permissons, same as for open() function
Using a FIFO is similar to using a file we can open, close, read, write, unlink, etc., to the FIFO
#include <sys/types.h>#include <sys/stat.h>
int mkfifo(const char *pathname, mode_t mode);
Returns: 0 if OK, -1 on error
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
19
#include <stdio.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>
main( ) {int fd;char str[100];unlink(“myPipe”);mkfifo(“myPipe”, 0660);fd = open(“myPipe”, O_RDONLY);
while (readLine(fd, str))printf(“%s\n”, str);
close(fd)}
20
readLine(int fd, char *str;{ int n;do {
n = read(fd, str, 1);} while (n>0 && *str++ != NULL);return (n>0);
}
21
#include <sys/types.h> #include <sys/stat.h>#include <fcnlt.h>main( ) {int fd, messageLen, i;char message[100];
sprintf(message, “Hello from PID %d”, getpid());messageLen= strlen(message)+1;do { fd = open(“myPipe”, O_WRONLY); if (fd == -1) sleep(1);} while(fd == -1);for (i =1; i<= 3; i++) {
write(fd, message, messageLen);sleep(3);
}close(fd);
}
22
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
24
25
Server
Server
Server
Client
Client
1. Sever creates a named socket
2. Client creates an unnamedsocket and request a connection
3. Server accepts a connection.Server retains original named socket
Server – Server creates a named
socket using socket()
– Server makes a peding 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
26
Client– Client creates an unnamed
socket using socket()
– Client requests a connection using connect()
– Client makes a connection when server accept( ) it.
클라이언트 서버
socket socket
bind
listen
accept
서비스 요청 처리
서비스 응답
close
응답 처리
connect
서비스 요청
close
연결 요청
EOF
다음 클라이언트로부터연결 요청을 기다림
소켓 만들기
int socket(int domain, int type, int protocol) domain
AF_UNIX AF_INET
type SOCK_STREAM
protocol DEFAULT _PROTOCOL
Examplefd = socket(AF_UNIX, SOCK_STREAM, DEFAULT_PROTOCOL);
28
소켓에 이름 ( 주소 ) 주기
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
29
serverUNIXAddress.sun_family = AF_UNIX;strcpy(serverUNIXAddress.sun_path, “convert”);unlink(“convert”);bind(fd, &serverUNIXAddress, serverLen);
30
소켓 큐 생성
int listen(int fd, int queueLength) specify the maximum number of pending connections
on a socket
examplelisten(serverFd, 5);
31
소켓에 연결 요청
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
32
소켓 연결 요청 수락
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
33
Convert Server/Client 이 프로그램은 입력 받은 문자열을 소문자를 대문자로 변환한다 .
서버 소켓을 통해 클라이언트로부터 받은 문자열을 소문자를 대문자로 변환하여 소켓을 통해 클라이언트에 다시 보낸다 .
클라이언트 표준입력으로부터 문자열을 입력 받아 이를 소켓을 통해 서버에 보낸 후에 소켓을 통해 대문자로 변환된 문자열을 다시 받아 표준출력에 출력한다 .
#include <stdio.h> #include <signal.h>#include <sys/types.h> #include <sys/socket.h> #include <sys/un.h>#define DEFAULT_PROTOCOL 0#define MAXLINE 100main ( ) { int listenfd, connfd, clientlen; char inmsg[MAXLINE], outmsg[MAXLINE]; struct sockaddr_un serverUNIXaddr, clientUNIXaddr; signal(SIGCHLD, SIG_IGN); clientlen = sizeof(clientUNIXaddr);
listenfd = socket(AF_UNIX, SOCK_STREAM, DEFAULT_PROTOCOL); serverUNIXaddr.sun_family = AF_UNIX; strcpy(serverUNIXaddr.sun_path, "convert");
35
Convert Server(1/3)
unlink("convert"); bind(listenfd, &serverUNIXaddr, sizeof(serverUNIXaddr)); listen(listenfd, 5);
while (1) { connfd = accept(listenfd, &clientUNIXaddr, &clientlen); if (fork ( ) == 0) { readLine(connfd, inmsg); toUpper(inmsg, outmsg); write(connfd, outmsg, strlen(outmsg)+1); close(connfd); exit (0); } else close(connfd); }}
36
Convert Server(2/3)
toUpper(char* in, char* out){ int i; for (i = 0; i < strlen(in); i++) if (islower(in[i])) out[i] = toupper(in[i]); else out[i] = in[i]; out[i] = NULL;}
37
Convert Server(3/3)
#include <stdio.h> #include <signal.h> #include <sys/types.h>#include <sys/socket.h>#include <sys/un.h>#define DEFAULT_PROTOCOL 0#define MAXLINE 100main ( ) { int clientfd, serverLen, result; char inmsg[MAXLINE], outmsg[MAXLINE]; struct sockaddr_un serverUNIXaddr;
clientfd = socket(AF_UNIX, SOCK_STREAM, DEFAULT_PROTOCOL); serverUNIXaddr.sun_family = AF_UNIX; strcpy(serverUNIXaddr.sun_path, "convert");
38
Convert Client(1/2)
do { result = connect(clientfd, &serverUNIXaddr, sizeof(serverUNIXaddr)); if (result == -1) sleep(1); } while (result == -1);
fgets(inmsg, MAXLINE, stdin); write(clientfd,inmsg,strlen(inmsg)+1); readLine(clientfd,outmsg); printf("%s --> \n%s", inmsg, outmsg); close(clientfd); exit(0);}
39
Convert Client(2/2)