Sie sind auf Seite 1von 37

EE 367L

Client Server Lab

University of Hawaii EE 367L

Outline
Big picture
Client server paradigm
Remote file server
Linux operations

How to call a Linux command from a program exec( )


How to get the output of a Linux command - pipes
How to call operations from a program fork( ) and wait( )
Processes

Remote file server


Client
Remote server
Sockets

University of Hawaii EE 367L

Server
Stdout
socket

Internet
(Cloud)

socket

Stdin Server
> ls
a.out
hello.c
hello
University of Hawaii EE 367L

Client Server Paradigm


Client

Issues commands
for service

Request service
(send command)
e.g., ls, cat, mov

Server
(e.g., wiliki)

Replies to request
e.g., data that satisfies
Listening for requests
the request
and then replies

University of Hawaii EE 367L

Linux commands
Linux commands are executed by software provided by
Linux
System calls: examples: ls, rm, cat, ....

Lets suppose you wanted to write a program that listed


the contents of your current directory on the panel
display
How do you implement ls from a program?
Option 1: Use very basic system calls, e.g., open(), write( ),
read( ), to emulate ls. This is basically writing the software
from scratch
Option 2: You can call ls using exec( ), or one of its
University of Hawaii EE 367L
variations

execl

Useful when you want to write a program X that calls


Linux commands such as rm, ls, cp
execl can be used to call these commands
It overwrites the existing process with another program
Example: execl(/bin/ls, ls, -l, (char *)NULL);
First parameter is the program that overwrites the current process
The next parameters are what would normally be typed by a Linux
user: ls -l
Second parameter is the first argument in the argument list, i.e., arg[0]
Third parameter is the second parameter in the argument list, i.e., arg[1]
Fourth parameter indicates thats the end of the argument list since the
parameter list has an arbitrary length

Another example: execl(/usr/bin/sh, sh, -c, ls l *.c, 0);


There are variations such
as execlp google to find
University of Hawaii EE 367L
6

Example

main()
{
execl(/bin/ls, ls, (char*) NULL
exit(EXIT_SUCCESS);
}

Overwrite
ls

eed to do more because the original program is completely overwritt

ant a program to
all a UNIX command
se data from the command and continue processing
University of Hawaii EE 367L

Solution
Original program (process) creates another child
program
The child program executes execl
The original is not overwritten and continues to run
This is implemented using the fork( ) system call
It creates a child process which is identical to the original
process
If theyre identical copies, how can a process tell whether its
the child or parent?
University of Hawaii EE 367L

Processes
Process is a running program sort of a virtual computer
Executable code
Memory for data, e.g., global variables, stack, heap (for dynamic
memory allocation)
CPU
Registers, such as general purpose registers, program counter, status control
registers, ...

Very simple computers run exactly one process


Examples: signal processing, embedded systems

General purpose computers can run multiple processes


The processes run like independent virtual computers

Multiple processes are created by the operating system and are


given process IDs (PIDs)
University of Hawaii EE 367L

Processes
main()
{
while(1) {
if (fork( ) == 0) { /* child */
task1( ):
exit(EXIT_SUCCESS);
}
else { /* parent */
task2( );
wait( );
}
}
}

Original parent process


fork() returns PID of child

Child process (a copy)


fork() returns 0

main()
main()
{
{
while(1) {
while(1) {
if (fork( ) == 0) { /* child */if (fork( ) == 0) { /* child */
task1( ): // child code
task1( ):
exit(EXIT_SUCCESS); // child code
exit(EXIT_SUCCESS);
}
}
else { /* parent */
else { /* parent */
task2( );
task2( ); // parent code
wait( );
wait( ); // parent code
}
}
}
}
}
}
k( ) creates an identical copy of the process,
called a child process. So now there is await(
child ) will stop the process until a child
process terminates
and the parent (original) process
running together
eturns
University of Hawaii EE 367L
0 if its a child process
10
PID of child if its the parent

Processes

/*

/*
Just one process
Multiple processes
*/
*/
main()
{
while(1) {
task1( ):
task2( );
}
}

P
C

main()
P
{
while(1) {
if (fork( ) == 0) { /* child */
P
task1( ):
exit(EXIT_SUCCESS); /* terminate the child. You can also just return */
}
P
else { /* parent */
task2( );
wait( ); /* wait for child to terminate */
}
}
}
University of Hawaii EE 367L

C
C

11

main()
{
if (fork( ) == 0) { /* child */
execl(/bin/ls, ls, (char*) NULL
exit(EXIT_SUCCESS);
}
else { /* parent */
task2( );
}
}

Processes

Parent

main()
{
f (fork( ) == 0) { /* child */
execl(/bin/ls, ls, (char*) NULL
exit(EXIT_SUCCESS);
}
else { /* parent */
task2( );
}
}

Child

main()
{
if (fork( ) == 0) { /* child */
execl(/bin/ls, ls, (char*) NULL
exit(EXIT_SUCCESS);
}
else { /* parent */
task2( );
}
}
University of Hawaii EE 367L

Overwrite
ls program

12

main()
{
if (fork( ) == 0) { /* child */
execl(/bin/ls, ls, (char*) NULL
exit(EXIT_SUCCESS);
}
else { /* parent */
task2( );
}
}

Processes

Parent

Child

main()
{
f (fork( ) == 0) { /* child */
execl(/bin/ls, ls, (char*) NULL
exit(EXIT_SUCCESS);
}
else { /* parent */
task2( );
}
}

ls

University of Hawaii EE 367L

Overwrite
ls program

13

Pipes
We still have a problem
The parent process can continue to run while ls is executing
So thats good

On the other hand, theyre independent


The parent process cannot get the data from the output of ls
ls will output to the stdio, which by default is attached to the display

We need the child to output to the parent rather than stdio


Create a pipe
Redirect the childs output to the pipe, its similar to a queue
The parent can input the data from the pipe
University of Hawaii EE 367L

14

Pipe a connection between


processes
Create a pipe
Operating System

int fd[2]; /* variables to hold fd values */

Pipe

pipe(fd);
fd[0] = read-end of the pipe
fd[1] = write-end of the pipe

Process

Process

You can write, read, close


Be sure to create a pipe before you fork so the
child and parent have access to the same fd values

University of Hawaii EE 367L

15

execl

Program X
Example 1: without pipe

Main program calls fork( ) to create a child


Child calls execl (ls......)
Child is overwritten by ls
The output of ls goes to stdio, which by default is your terminal

Example 2: with pipe

Main program creates a pipe, and receives file descriptors


Main program (parent) creates a child
Child redirects stdio to the pipe using dup2
Child calls execl(ls...) output goes through the pipe
Parent receives the output through the pipe

University of Hawaii EE 367L

16

Example 1

main()
{
fork( )
}

Parent
main()
{

Child
main()
{

Overwrite

execl program, e.g., ls


}
}

ls program

Output

Child will run ls, which now sends


output to stdio, which by default is
the terminal

University of Hawaii EE 367L

17

Example 2

Parent
main()
{
Listen to pipe
Process what comes
}

main()
{
Make a pipe
Bind file descriptors
fork( )
}
pipe

Child
main()
{
Redirect output from stdio to pipe
using dup2
execl program, e.g., ls
}

University of Hawaii EE 367L

18

Example 2

Parent
main()
{
Listen to pipe
Process what comes
}

main()
{
Make a pipe
Bind file descriptors
fork( )
}
pipe

Child
main()
{
Redirect output from stdio to pipe
using dup2
execl program, e.g., ls
}

University of Hawaii EE 367L

19

Example 2

Parent
main()
{
Listen to pipe
Process what comes
}

main()
{
Make a pipe
Bind file descriptors
fork( )
}
pipe

Child
main()
{
Redirect output from stdio to pipe
using dup2
execl program, e.g., ls
}

University of Hawaii EE 367L

Complete
Overwrite
ls program

20

execl, etc

There is a program pipe.c in the project that shows how


to use execl, dup2, and pipes
Read it, compile it, and run it

University of Hawaii EE 367L

21

Server
> ls
a.out
hello.c
hello

Client X
socket

Internet
(Cloud)

Server Y
socket

Key issue: how do we


transport over the
3. Listening
cloud
1. User types ls
4. Receives message for
2. Sends a message to server Y
an ls from client X
requesting ls
5. Executes the ls
6. Sends the output to
7. Waits for a reply from Y
client X
8. Gets reply and outputs to user
University of Hawaii EE 367L

22

File Transfer

Typical system calls (to the operating system)


fd = fopen(filename, w);
Operating system creates a file in the local server (e.g.,
local disk drive)
It gives the file an name filename and this is recorded
somewhere by the operating system
Operating system assigns the file a file descriptor number
(fd)
From this point, the file is referenced using fd
fprintf(fd, Hello world);
fclose(fd);
Even simpler is write( ) and read( )
Remote files
University of Hawaii EE 367L

23

Sockets
Two types
Stream sockets
Long lived connection between two entities
Based on the TCP protocol
Well concentrate on this type of socket
Datagram sockets
One message (datagram)
Based on the UDP protocol
University of Hawaii EE 367L

24

Sockets
Applications
TCP Ports

Client

Server

TCP protocol

TCP protocol

Internet Network
(Network Layer IP protocol)

port = IP address
128.15.20.0
somewhere.com
ain name for the
dress
ain Name System (DNS) is used to convert a domain name into an IP address
University of Hawaii EE 367L

25

Components to set up a Socket


Get information for a socket
Client
IP address
Converted from a url, such as www.ee.hawaii.edu which requires DNS
service

TCP port number


Type of socket, e.g., datagram versus stream

Server
TCP port number
Type of socket

Set up the socket, acquire file descriptor fd


send/recv using fd
University of Hawaii EE 367L

26

Sockets getting the information

getaddrinfo(www.example.com , http, &hints, &res)


www.example.com is the host name (IP address) to connect to -input
Second parameter is a port number -- input
Alternatively, you can use http if its the port for the http connections

hints has data that to be used to set up the connection input

Examples
hints.ai_family = AF_UNSPEC;
// Dont specify IPv4 or IPv6
hints.ai_socktype = SOCK_STREAM;
// or SOCK_DATAGRAM
hints.ai_flags = AI_PASSIVE;
// Assign local host to IP address
structure

ee http://beej.us/guide/bgnet/output/html/multipage/syscalls.html
res
isand
thethere
output
or results
and
this that
is inyou
a can
linked
or these system
calls
is an example
called
showip.c
run
s in section ouput
5.1
University of Hawaii EE 367L

list form -27

Sockets

getaddrinfo(www.example.com ,http, &hints, &res);


sockfd = socket(res->ai_family, res->ai_socktype, res>ai_protocol);
sockfd is the socket file descriptor, similar to a file descriptor
Points to information needed to set up a connection
To make a connection, sockfd needs to bind itself to a port # or IP
address/port#
It depends on whether it is a client or server

University of Hawaii EE 367L

28

Client-Server
Request
Client
Initiates Transaction

Server
Reply

Waits for
requests

Request connection
to a port X / IP address
Provides its own port#/IP addr

Client
Initiates connection

Reply

send
recv
University of Hawaii EE 367L

Waits for
requests to
Server
connect to
port X
no IP addresses needed
send
recv
29

Client Socket
getaddrinfo(www.example.com ,3490, &hints, &res);
sockfd = socket(res->ai_family, res->ai_socktype, res>ai_protocol);
Now sockfd is the socket file descriptor, similar to a file descriptor

Client
connect(sockfd, res->ai_addr, res->ai_addrlen);
This will connect to the remote address www.example.com specified
in res->ai_addr and on port 3490

University of Hawaii EE 367L

30

Server Socket
getaddrinfo(www.example.com ,http, &hints, &res);
sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
Now sockfd is the socket file descriptor, similar to a file descriptor

Server:

hints.ai_flags = AI_PASSIVE;
// use local address
getaddrinfo(NULL, 3490, &hints, &res);
socketfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
bind(int sockfd, res->ai_addr, res->ai_addrlen);

Binds sockfd data structure to the local IP address and port 3490
sockfd = socket file descriptor
res->ai_addr = pointer to address information: port number
res->ai_addrlen = length in bytes of the address

Server can now listen on sockfd


When it has a request, it can accept
University of Hawaii EE 367L

31

listen( ) for
connection
requests at
connect( ) port 4000
port 4000

Client-Server

Process
Client
Process
(Server)

Client
okay

Client

is busy

port 6059

okay

connect( )
port 4000

Process
(Server)

connect( )
port 4000

accept( )
Child
new port 6059
new sockfd

Process
Client
is not busy

University of Hawaii EE 367L

32

Sockets
Client will connect to a server
connect(sockfd, res->ai_addr, res->ai_addrlen);
This will connect to the remote IP address specified in res->ai_addr.
Port # from sockfd

Server waits/listens for connections from clients


int listen(int sockfd, int backlog);
Calls (connection requests) arrive at the server and are queued until
they are accepted
backlog = maximum number incoming calls in a queue
It listens on a port, say port 1234

int accept(int sockfd, structaddr *addr, socklen_t *addrlen);


This will take a call from the queue and assign it its own port number,
say port 4567
In this way port 1234 can still be used for incoming calls
University of Hawaii EE 367L
accept returns another socket file descriptor for this connection

33

Sockets

send(int sockfd, const void *msg, int len, int flags );


msg is the buffer of data to send
len is the length
flags can be set to 0

recv( int sockfd, void *buf, int len, int flags);


buf is where the data is received
flags can be set to 0

University of Hawaii EE 367L

34

Client Server
Client

Server

Create socket
Connect

Create socket
Call queuelisten

send
recv
University of Hawaii EE 367L

accept
Get a new socket fd
Create a child process
to use this new fd

35

Ideas

Break up the programming problem into smaller chunks so that you can
test it
Example:
Part 1: Use the client server programs from Beejs guide. Run them to make sure they
work
Part 2: Modify the server so that it executes ls every time it gets a connection request
from the client. Note the output of ls goes to the console of the server. The server then
terminates the connection.
This will give you experience with execl and processes (and also maybe pipes)

Part 3: Modify the server so that it executes ls every time it gets a connection request
from the client but the output of ls goes through the socket back to the client. The server
will terminate the connection. The client will display the output
This will give you experience with pipes as well as sockets

Part 4: Modify the client so that it accepts the three commands (list, check
<filename>, and get <filename>) from the user, starts a connection per command,
sends a message to indicate the command to the server (e.g., list, check <file name>,
get <file name>). The server is modified so that it accepts the connection, prints the
command on its own console, executes ls, sends the output of ls back to the client.
Part 5: Complete the project
University of Hawaii EE 367L

36

Ideas
Hint:
Model: client sends request -> server process replies
Have each transaction correspond to a new connect, i.e.,
terminate a connection after a reply

University of Hawaii EE 367L

37

Das könnte Ihnen auch gefallen