Architecture and Network Programming
8sif120
Lab #1 (due date : Oct 10th 2020) Paul Girard, Ph.D.
Objective
Implement the FTP "put" function ==> put local_file_name remote_ file_name
using the client-server concept and the TCP socket functions. The put function will
support an ASCII file transfer from the client to the server. Each message will be a
logical record read from a local text file and send through a tcp socket to the server until
the end of file (test feof on local_file).
Methodology
1. Login on dim-ensxcn1.uqac.ca using putty; specify your user account and password.
(see Appendix C)
- copy the following 4 files with the command cp to the server dim-ensxcn1.uqac.ca
$ cp ../web00300/client_base.c .
$ cp ../web00300/compbasec .
$ cp ../web00300/tp2dat1 .
$ cp ../web00300/tp2dat3 .
- Do a login on dim-ensxcn2.uqac.ca and copy the following 2 files to this server
$ cp ../web00300/server_base.c .
$ cp ../web00300/compbases .
2. Use EditPlus to open source (.c) file locally and save them locally (USB key or hard
disk).
3. Change the protection of compbasec and compbases to be executable on each server
$ chmod 700 compbasec
$ chmod 700 compbases
4. Compile each program client_base.c and server_base.c with the previous command
files on each server :
(dim-ensxcn1) $ ./compbasec
(dim-ensxcn2) $ ./compbases
5. Now execute these 2 programs in the following order. The output should be the same
as shown in Appendix A
on dim-ensxcn2: $ ./server_base 5xxx (xxx are the 3 last digits of your userid on dimensxcn2.uqac.ca
[web00xxx])
on dim-ensxcn1: $ ./client_base dim-ensxcn2.uqac.ca 5xxx
remark: Use Ctl C to kill the server process1 when the execution is completed
1 The unix command netstat -a displays all sockets used and their status
8sif120/lab1 ©Paul Girard Ph.D. page 2 of 9
5. - Now that you know how to execute these basic programs rename each one with the
Unix command mv
client_base.c ===> client_ftp.c
server_base.c ===> server_ftp.c
(ex. mv client_base.c client_ftp.c)
- Create the two new compilation procedures for these 2 programs with EditPlus
[web00***@dim-ensxcn1]$ more complab1c
gcc client_ftp.c -lnsl -lrt -o client_ftp
[web00***@dim-ensxcn2]$ more complab1s
gcc server_ftp.c -o server_ftp
6. Read the code of each client and server base programs to understand
the protocol and the timing of execution.
Then modify the program client_ftp.c to transfer an ASCII file to the server
- Delete the code for the 1 second delay (sleep) and the actual DATA message.
- The program waits from keyboard a command line the having 3 parameters (only put
is supported):
put local_filename remote_filename
DO NOT ENTER THIS COMMAND USING 3 scanf, IT MUST BE ENTERED
USING A SINGLE LINE.
After a successful opening (read mode) of the local file, the extracted remote file name
will be transmitted to the server. The client program will then wait until it receives the
message "ACK" from the server; this message will be transmitted by the server as
soon as the server will open successfully (write mode) the file whose name has been
transmitted by the client (remote_file). Display a short message specifying that the
server is now ready to receive the file local_file. If the server was not able to open this
file in a write mode, a "NAK" message will be sent to the client which will close the
socket. The client will then have to reconnect and request a new remote file name.
- The client will then read the Unix timer with the function clock_gettime() which
returns the current high-resolution in real time. Time is expressed in seconds AND
nanoseconds since some arbitrary time in the past. Each logical record of the local file
will then be read and transmitted immediately to the server; each record read by the
server will be written in its own file. A message from the client to the server
contains only one logical record and not the complete file. The timer will be read a
second time after the end of file in order to calculate the transfer delay in milliseconds
and the transfer rate in Koctets/second. The number of logical records read will be
displayed and the number of octets transfered. The delay is the time just before calling
connect() and immediately after the close() of the socket.
8sif120/lab1 ©Paul Girard Ph.D. page 3 of 9
Example using clock_gettime ()
struct timespec time1, time2, temp; /* time_t tv_sec; seconds
long tv_nsec; nanoseconds */
double delay;
...
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time1); /* read the timer1 nanosec*/
... ==> file transfer where lines sent and octets sent are saved
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2); /*read the timer2 in nanosec*/
/* Statistics */
if ((time2.tv_nsec-time1.tv_nsec)<0)
{
temp.tv_sec = time2.tv_sec-time1.tv_sec-1;
temp.tv_nsec = 1000000000+time2.tv_nsec-time1.tv_nsec;
} else
{
temp.tv_sec = time2.tv_sec-time1.tv_sec;
temp.tv_nsec = time2.tv_nsec-time1.tv_nsec;
};
delay = (double)((temp.tv_sec * 1000000) + (temp.tv_nsec/1000)); /* delay in microsec*/
delay = (double)delay/1000; /* delay in msec */
printf("File %s had %d lines and a total of %d octets\n",filename_local, nline, noctets);
printf("Transfer rate : %9.3f MO/sec \t Transfer delay:%9.3f msec\n",
(double)((noctets*0.9765)/(1024*delay)),delay);
- The client will close its socket and the file. A message "End of program" will be
displayed on the screen.
- You should use the following functions in the client program :
fgets(buf, 81, fptr) to read a logical record of the file,
fclose(fptr) to close the file.
feof(fptr) to test the end of file
- Each file tp2dat* (do not change the content or the name) will be opened in a read
mode by the client program. The following example shows how to read a file name on
the terminal and open it in a read mode.
8sif120/lab1 ©Paul Girard Ph.D. page 4 of 9
FILE *fptr; /*pointer to file descriptor*/
char filename[20];
char buf[81]; /* buffer */
.......
puts("Name of the file to transmit ? ");
gets(filename);
if ((fptr = fopen(filename, "r")) == NULL)
{
perror("error opening this file");
exit (0);
}
...
while (fgets(buf, 81, fptr)); /* read a file record */
{
...
}
10. Modify the program server _ftp.c receiving an ascii text file from the client :
- Modify the actual DATA message for "ACK" and create another DATA message
“NAK”
- The server must never stop. When a client connection is accepted, the server displays
a message like "Connection accepted". The server will then wait for a message from the
client. After a successful connection from a client, the server read the name of a new
file to be received later by the client. The server will display this file name. If this file
is successfully opened in a write mode, the server will then send an ACK message to the
client. If the client receives this ACK, it will begin the transmission of a series of
message (one message/logical record). If the server cannot open the file in a write mode
a NAK will be transmitted to the client and the server will go back in a listening mode
(accept) after printing a message. If the ACK has been transmitted, the server will read
each message from the client and write each logical record to the file opened in a write
mode. At the end of transmission, the server will display the number of received octets.
This number should correspond to the number of octets sent by the client (and the size
of this file on the operating system with the Unix command ls -ls).
8sif120/lab1 ©Paul Girard Ph.D. page 5 of 9
Client - Server Synchronization
1. The server waits for a client connection
2. The client reads the command line
“put local_file_name remote_file_name”.
it opens the local file,
if successful, it does a connect to the server
and if successful, it transmits the name of
the remote file to the server and waits ====>
3. The server receives the file name & opens it
in a write mode. If successful, it transmits an
ACK to the client , if not then a NAK will be
transmitted and the server closes the client
connection and returns to a wait state (step 1.)
<=====
4. The client receives and validate the
ACK/NAK.
If it is a NAK, a message is printed
by the client and then exit
If it is an ACK, a logical record is read
from the file and sent to the server.
=====> 5. The server receives the message and write a
logical record to its file and waits for the next
message until the end of transmission.
6. Each record is read and sent to the server
until feof(). At the end, it closes the socket
and the file. =====> 7. When the client socket is closed TCP sends
an end of connection to the server. The server
then closes the client connection, closes the
file and waits for another client connection
(step 1)
- The following functions should be used by the server :
fputs(buf, fptr) to write a logical record in a file,
fclose(fptr) to close the file.
Example of a file creation
FILE *fptr;
char buf[81];
char filename[20];
.......
the filename is transmitted by client_ftp
if ((fptr = fopen(filename, "w")) == NULL);
{ perror("error opening this file");
exit (0);
}
...
fputs(buf, fptr); /* write a record to a file */
8sif120/lab1 ©Paul Girard Ph.D. page 6 of 9
Lab report
Verify the output of client_ftp and server_ftp in Appendix B before doing your final
report (one report for one team). The report will have the following components.
1) The name of each team member and their student code, the userid and password
to test it
2) The list of each source program (client_ftp.c and server_ftp.c) ; do not change the
name of these programs. DO NOT MODIFY THE ACTUAL COMMENTS.
3) An example of execution showing the two original file transfers (tp2dat1 et tp2dat3)
by copying each line for the client and the server telnet session. Do the command ls –ls
to show the size of your files. DO NOT MODIFY THOSE FILES.
4) DO NOT COPY AN EXAMPLE FROM THE INTERNET ==> 0
Print and give the report to the assistant professor before due date. Do not forget to give
your userid, your password and the name of the subdirectory if you created one. We
must be able to execute your programs and display the source.
8sif120/lab1 ©Paul Girard Ph.D. page 7 of 9
Appendix A
Execution of server_base
(SSH #1 with dim-ensxcn2.uqac.ca)
[pgirard@dim-ensxcn2 tut_sif120]$ ./compbases
[pgirard@dim-ensxcn2 tut_sif120]$ ./server_base 5001
The port number used by the tcp socket is #5001
server ready for connection
Client connection
=====>Dummy message from client to the server using tcp
=====>Dummy message from client to the server using tcp
=====>Dummy message from client to the server using tcp
=====>Dummy message from client to the server using tcp
=====>Dummy message from client to the server using tcp
=====>Dummy message from client to the server using tcp
=====>Dummy message from client to the server using tcp
=====>Dummy message from client to the server using tcp
=====>Dummy message from client to the server using tcp
=====>Dummy message from client to the server using tcp
End of client connection
Execution of client_base
(executed after server_base using SSH #2 with dim-ensxcn1)
[pgirard@dim-ensxcn1 tut_sif120]$ ./compbasec
[pgirard@dim-ensxcn1 tut_sif120]$ ./client_base dim-ensxcn2 5001
===> Dummy message from server : acknowledge client message
===> Dummy message from server : acknowledge client message
===> Dummy message from server : acknowledge client message
===> Dummy message from server : acknowledge client message
===> Dummy message from server : acknowledge client message
===> Dummy message from server : acknowledge client message
===> Dummy message from server : acknowledge client message
===> Dummy message from server : acknowledge client message
===> Dummy message from server : acknowledge client message
===> Dummy message from server : acknowledge client message
End of client program
[pgirard@dim-ensxcn1 tut_sif120]$
8sif120/lab1 ©Paul Girard Ph.D. page 8 of 9
Appendix B
Execution of server_ftp with 2 requests
(telnet #1 on dim-ensxcn2)
[pgirard@dim-ensxcn2 tut_sif120]$ ./server_ftp 5001
The tcp socket port number is #5001
Server ready for connections
Client connection
=====>test3
End of client file transfer
File test3 has 87969 octets
Client connection
=====>test1
End of client file transfer
File test1 has 1497 octets
Execution of client_ftp (3 exec)
(telnet #2 on dim-ensxcn1)
[pgirard@dim-ensxcn1 tut_sif120]$ ./client_ftp dim-ensxcn2.uqac.ca 5001
myftp> put tp2dat3 test3
ftp command=> put local file=> tp2dat3 remote file=> test3
File tp2dat3 had 1100 lines and a total of 87969 octets
Transfer rate : 43.086 MO/sec Transfer delay: 1.947 msec
End of program
[pgirard@dim-ensxcn1 tut_sif120]$ ./client_ftp dim-ensxcn2.uqac.ca 5001
myftp> put tp2dat1 test1
ftp command=> put local file=> tp2dat1 remote file=> test1
File tp2dat1 had 56 lines and a total of 1497 octets
Transfer rate : 11.513 MO/sec Transfer delay: 0.124 msec
End of program
8sif120/lab1 ©Paul Girard Ph.D. page 9 of 9
Appendix C
Examples of C functions used in lab 1
1) scanf : used to read string (s) on the keyboard
2) strcmp : used to compare 2 strings
For example, the following instructions read a filename and a file type. We accept only
the text file type . If this not a text file, print an error message and exit.
char type[16]; /* file type */
char filename [20]; /* name of a file */
...
printf("Please enter the file name and the file type > ");
scanf("%s %s ", filename, type); /* read the filename and the file type on the
keyboard /*
if (strcmp(type,"text") != 0) /* if type is not text then error and exit */
{
printf("Error : the file type %s is not supported \n", type);
return 1;
}
...