Sei sulla pagina 1di 24

Homework 1 Design Issues

1) The server should be concurrent. This implies that it should loop


infinitely, listening for clients requests. It should NOT terminate after
accepting the first connection.
while( 1 ) /* loop forever */
{
/* recieve a new connection */
newSocketDes = getConnection( socketDes, socketInfo );
if( fork() == 0 ){
close( socketDes );
/* retrive the filename */
getFileName( newSocketDes, fileName );
/* Get the requested data */
retrieveData( newSocketDes, fileName );
exit( 0 );
}

Homework 1 Design Issues


close( newSocketDes );
}
exit( 0 );
}
2) The names for the requested and delivered files should be the same.
/* send the file name */
sendMessage( socketDes, argv[ 3 ] );
/* get the file */
getMessage( socketDes, argv[ 3 ] );

Homework1 Design Issues


3. The size of the file after the transfer should be the same as that on the

server. That is, no extra characters should be written by the server or


the client.
Server side
int result = 1;
fileDes = open( fileName, O_RDONLY );
while( result > 0 )
{
/* read the info */
result = read( fileDes, message, MAXBUF );
/* write the info */
if( result != -1 )
write( socketDes, message, result );
}
/* We are all done, close the file */
close( fileDes );

Homework1 Design Issues


Client side
int messageLength = 1;
/* Open the file in write mode */
fd = open( filename, O_CREAT|O_RDWR,S_IREAD|S_IWRITE);
while( messageLength > 0)
{
/* get the file from the socket */
messageLength = read( socketDes, message, MAXBUF );
if( messageLength != 0)
/* Write the contents of the file (message) into the file */
write(fd, message, messageLength);
}

Homework1 Design Issues


4. Preferably, the rate at which you are sending the data (number of writes
and reads to/from the socket) should be optimized. This means that the
maximum possible number of bytes must be read/written per read/write call.
You should be able to easily change this number without affecting the
rest of the program (for example, by changing MAXBUF value in common.h,
without any changes to other C files).
#define MAXBUF 1024 /* maximum buffer size for reading and writing
messages */

FTP
RFC (Request For Comments) 959
http://www.ietf.org/rfc.html
The File Transfer Protocol
was defined as a protocol for file transfer between HOSTs on the ARPANET, with the
primary function of FTP defined as transferring files efficiently and reliably among
hosts and allowing the convenient use of remote file storage capabilities.
There are 2 channels:
1.
Control Channel (port 21)
FTP commands and replies
Eg:
ftp draco
Connected to draco.ece.arizona.edu.
220 gauss FTP server (SunOS 5.8) ready.
2.

Data Channel (port 20)

THE FTP MODEL


User
Interface

File
system

Server
PI

FTP Commands

Server
DTP

Data
Connection

Server Side

FTP Replies

User

User PI

User
DTP

Client Side

File
system

FTP
PI
Protocol Interpreter
DTP Data Transfer Process
Examples of protocol interpretation
Client
ls
get
put

Server
STAT .
retr
stor

Connection Oriented Protocol


Server
socket()
bind()
listen()
accept()

Client

socket()
connection establishment connect()
read() data(request)
write()
blocks until connection from client

process request

write()
read()

data (reply)

Connectionless Protocol
Server
socket()
bind()
recvfrom()
Client
blocks until connection from client

bind()
data (request)

sendto()

process request

write()
data (reply)
recvfrom()

socket()

System Calls
int sendto (int socket, char *message, int nbytes, int flags, struct sockaddr
*dest, int dest_len);
Description
The sendto() function sends a message through connectionless-mode
socket.The message will be sent to the address specified by dest.
The system call takes the following arguments:
socket
Specifies the socket descriptor.
message
Points to a buffer containing the message to be sent.
nbytes
Specifies the size of the message in bytes.

System Calls
dest
Points to a sockaddr structure containing the destination address. The
length and format of the address depend on the address family of the
socket.
dest_len
Specifies the length of the sockaddr structure pointed to by the dest
argument.
flags
Values of this argument are formed by logically OR'ing zero or more
of the following flags

System Calls
int recvfrom (int socket, char *message, int nbytes int flags, struct
sockaddr *from, int *from_len);
Description
The recvfrom() function call receives a message from a connectionlessmode socket.
The recvfrom system call fills in the protocol specific address of who sent
the data into from . The length of this address is also returned to the
caller in from_len.

UDP Echo Server


/*
* Header file
*/
#include
<stdio.h>
#include
<sys/types.h>
#include
<sys/socket.h>
#include
<netinet/in.h>
#include
<arpa/inet.h>
#define SERV_UDP_PORT 6000
#define SERV_HOST_ADDR "128.196.28.78" /* host addr for server */

UDP Echo Server


/*
* Example of server using UDP protocol.
*/
#include "inet.h"
main(argc, argv)
int argc;
char *argv[];
{
int
sockfd;
struct sockaddr_in serv_addr, cli_addr;
/*
* Open a UDP socket (an Internet datagram socket).
*/
if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
perror("server: can't open datagram socket");

UDP Echo Server


/*
* Bind our local address so that the client can send to us.
*/
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port
= htons(SERV_UDP_PORT);
if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
perror("server: can't bind local address");
dg_echo(sockfd, (struct sockaddr *) &cli_addr, sizeof(cli_addr));
}

UDP Echo Server


/*
* Example of client using UDP protocol.
*/
#include
"inet.h"
main(argc, argv)
int argc;
char *argv[];
{
int
sockfd;
struct sockaddr_in
cli_addr, serv_addr;
/*
* Fill in the structure "serv_addr" with the address of the
* server that we want to send to.
*/
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family
= AF_INET;
serv_addr.sin_addr.s_addr = inet_addr(SERV_HOST_ADDR);

UDP Echo Server


serv_addr.sin_port
= htons(SERV_UDP_PORT);
/*
* Open a UDP socket (an Internet datagram socket).
*/
if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
perror("client: can't open datagram socket");
/*
* Bind any local address for us.
*/
bzero((char *) &cli_addr, sizeof(cli_addr)); /* zero out */
cli_addr.sin_family = AF_INET;
cli_addr.sin_addr.s_addr = htonl(INADDR_ANY);
cli_addr.sin_port
= htons(0);
if (bind(sockfd, (struct sockaddr *) &cli_addr, sizeof(cli_addr)) < 0)
perror("client: can't bind local address");

UDP Echo Server


dg_cli(stdin, sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
close(sockfd);
exit(0);
}

UDP Echo Server


/*
* Read a datagram from a connectionless socket and write it back to
* the sender.
* dg_echo()
* We never return, as we never know when a datagram client is done.
*/
#include
<sys/types.h>
#include
<sys/socket.h>
#define MAXMESG 2048
dg_echo(sockfd, pcli_addr, maxclilen)
int
sockfd;
struct sockaddr *pcli_addr; /* ptr to appropriate sockaddr_XX structure */
int
maxclilen; /* sizeof(*pcli_addr) */
{
int n, clilen;
char mesg[MAXMESG];

UDP Echo Server


for ( ; ; ) {
clilen = maxclilen;
n = recvfrom(sockfd, mesg, MAXMESG, 0, pcli_addr, &clilen);
}
if (n < 0)
perror("dg_echo: recvfrom error");
if (sendto(sockfd, mesg, n, 0, pcli_addr, clilen) != n)
perror("dg_echo: sendto error");
}
}

UDP Echo Server


/*
* Read the contents of the FILE *fp, write each line to the
* datagram socket, then read a line back from the datagram
* socket and write it to the standard output.
*dg_cli()
* Return to caller when an EOF is encountered on the input file.
*/
#include
#include
#include

<stdio.h>
<sys/types.h>
<sys/socket.h>

#define MAXLINE 512


dg_cli(fp, sockfd, pserv_addr, servlen)
FILE
*fp;
int
sockfd;
struct sockaddr *pserv_addr; /* ptr to appropriate sockaddr_XX structure */
int
servlen;
/* actual sizeof(*pserv_addr) */
{

UDP Echo Server


int n;
char sendline[MAXLINE], recvline[MAXLINE + 1];
while (fgets(sendline, MAXLINE, fp) != NULL) {
n = strlen(sendline);
if (sendto(sockfd, sendline, n, 0, pserv_addr, servlen) != n)
perror("dg_cli: sendto error on socket");
/*
* Now read a message from the socket and write it to
* our standard output.
*/
n = recvfrom(sockfd, recvline, MAXLINE, 0,
(struct sockaddr *) 0, (int *) 0);
if (n < 0)
perror("dg_cli: recvfrom error");
recvline[n] = 0;
/* null terminate */
fputs(recvline, stdout);
}

UDP Echo Server


if (ferror(fp))
perror("dg_cli: error reading file");
}

Potrebbero piacerti anche