Beruflich Dokumente
Kultur Dokumente
1. INTRODUCTION
1.1
Purpose
A file is a fundamental abstraction for long-term storage of information. Transferring files
from one computer to another is one of the most common tasks expected from networking or inter networking environment. The greatest volume of data exchange in Internet today is due to file transfer. It is always essential that information and files are geographically distributed over different locations be shared among the members of work group. Although transferring file from one system other seems simple and straight forward, some problems must be dealt.
Every computer file is a series of numerical values stored as series of single objects. Whether those values represent text (in ASCII format), an image (such as a JPEG or GIF) or any other type of contents. All files require some sort of interpretation. What the file represents, and how the data in the file should be interpreted, depends on the files content type( file type). A files content type is extremely important, since processing an image file with an audio processor would end in a meaningless result .Different system may different ways of representing data and text , may use different filename conversion and may have different directory structures. All these problems have been solved by File transfer protocol. The File Transfer Protocol is an excellent method to transfer (download and send) files from one computer to the other over the Internet. Though you can transfer files using email, it is not a good choice especially when the file size is large or when you need to transfer several files. The main purpose of our project is to understand the working of the connection oriented protocol TCP/IP works and to develop a file transfer protocol. The file transfer protocol is an initial approach to standard file transfer protocol which is generally adopted in the working environment. internet-
Feb-June-2012
1.2 Scope
File Transfer protocol is the standard mechanism provided by TCP/IP for copying file from one host to another host. It is an application layer protocol.
Promote file (programs or data) sharing Efficiently transfer data from one computer to another Encourage indirect or implicit use of remote computers Provide a common platform for file storages among different
hosts.
FTP transfers arbitrary data, e.g. text and binary files access restrictions
Provides security (before using the client must login with correct
name and password).
Feb-June-2012
Product perspective:
The file transfer protocol should be able to provide the basic and easy way to communicate between two systems. And the protocol should be able to give the maximum options as possible for the user. The protocol should work between many systems. The protocol should provide many options as possible for the user. The FTP server is able to server the request many client at a time.
Feb-June-2012
2.2.3. Interfaces
This section describes how the client interacts with the server.
Client side
Processor: Intel Pentium 4 or higher version RAM: 256 MB or more Hard disk: 5 GB or more
3. DETAILED DESIGN
The ftp model developed is based on the client server architecture using the concept of socket programming .ftp setups the two connection one for data and other control connection. The control connection will be opened always but data connection will be opened as and when required. The ftp model contains two model mainly client and server.
3.1.2 Purpose
The server module create socket, bind server to port 1234(registered port).it wait for client connection to complete. It is concurrent server which can handle multiple request at a time. After client gets connected to it will send the command using control connection and set ups data connection as an when required.
3.1.3 Functionality
SERVER: 1. Initially server creates socket.
Feb-June-2012
3.1.4 Input
The server will given specific IP address and the port no 1234 (registered port).
3.1.5 Output
The server will bind to the specific address wait for the connection requset from the client.As per the request it will exectue the different commands of ftp.
3.2.2 Purpose
The client module create socket, fill in internet socket address structure. It will send the request to server for connection. After client gets connected to server will send the command us-
Feb-June-2012
3.2.3 Functionality
Client:
1.
Initially the client also creates the socket using the socket system call. Authentication is done.
2.It then calls the connect system call for establishing the connection to the server.
3.
4.The file transfer takes place between client and server. (Using series of read and write operations)
3.2.4 Input
The client will be given server IP address and the port no 1234 (registered port).
3.2.5 Output
The client will send to the specific address wait for the connection reply from the server.As per the permission client can ask for the request.
Feb-June-2012
4. IMPLEMENTATION
4.1
The figure shows basic model of ftp. The client has 3 components: user interface, control process, and client data transfer. The server has 2 components: control process and data transfer process. The control connection is made between the data transfer process and remains open for the entire interactive ftp session. The data connection is opened for each file transferred. It opens each time commands that involve transferring files are used and it closes when the file is transferred.
4.2
Introduction to Sockets
Among the many methods available for sending data or files on network media, Sockets can provide faster access than most of the other methods we study, usually with very little overhead, and it is adaptable to most types of Networks. Though rarely appreciated, sockets make it possible to send any data within the network most efficiently.
Feb-June-2012
Implementation
A socket is actually a function that creates an end point for communication. For two processes to communicate sockets should be created at both ends. After sockets have been created then a path is established between the two processes, using which we can transfer the data from one process to another. Using Sockets we can establish communication between two unrelated processes which are over a network. These advantages of sockets are appreciated when network programming is undertaken. LINUX Operating system while being a very flexible and robust O.S also has a very good support for programming especially with C/C++. Sockets are typed according to the communications properties visible to the user. Applications are presumed to communicate only between sockets of the same type; although there is nothing that prevents communication between sockets of different types should underlying communication protocols support this. Two types of sockets are available to the user. A stream socket provides for the bi-directional, reliable, sequenced, and unduplicated flow of data without record boundaries. A datagram socket supports bi-directional flow of data which is not promised to be sequenced, reliable, or unduplicated.
Feb-June-2012
Implementation
When you have finished using a socket, you can simply close its file descriptor with `close'; see *Note Opening and Closing Files`. If there is still data waiting to be transmitted over the connection, normally `close' tries to complete this transmission. You can control this behavior using the `SO_LINGER' socket option to specify a timeout Period. You can also shut down only reception or transmission on a connection by calling `shutdown', which is declared in `sys/socket.h'. - Function: int shutdown (int SOCKET, int HOW) The `shutdown' function shuts down the connection of socket SOCKET. The argument HOW specifies what action to perform: `0' Stop receiving data for this socket. If further data arrives, reject it. `1' Stop trying to transmit data from this socket. Discard any data waiting to be sent. Stop looking for acknowledgement of data already sent; don't retransmit it if it is lost. `2' Stop both reception and transmission. The return value is `0' on success and `-1' on failure. The following `errno' error conditions are defined for this function
Feb-June-2012
10
Implementation
4.2.2.1 Making a Connection
In making a connection, the client makes a connection while the server waits for and accepts the connection. Here we discuss what the client program must do with the `connect' function, which is declared in `sys/socket.h'. - Function: int connect (int SOCKET, struct sockaddr *ADDR, socklen_t LENGTH) The `connect' function initiates a connection from the socket with file descriptor SOCKET to the socket whose address is specified by the ADDR and LENGTH arguments. (This socket is typically on another machine, and it must be already set up as a server.) Normally, `connect' waits until the server responds to the request before it returns. You can set nonblocking mode on the socket SOCKET to make `connect' return immediately without waiting for the response. *Note File Status Flags: For information about nonblocking mode. The normal return value from `connect' is `0'. If an error occurs, `connect' returns `-1'. 4.2.2.2 Listening for connections Now let us consider what the server process must do to accept connections on a socket. First it must use the `listen' function to enable connection requests on the socket, and then accept each incoming connection with a call to `accept' (*note Accepting Connections ::). Once connection requests are enabled on a server socket, the `select' Function reports when the socket has a connection ready to be accepted. The `listen' function is not allowed for sockets using connectionless communication styles. - Function: int listen (int SOCKET, unsigned int N) The `listen' function enables the socket SOCKET to accept connections, thus making it a server socket.
Feb-June-2012
11
Implementation
The argument N specifies the length of the queue for pending connections. When the queue fills, new clients attempting to connect fail with `ECONNREFUSED' until the server calls `accept' to accept a connection from the queue. The `listen' function returns `0' on success and `-1' on failure. 4.2.2.3 Accepting connections When a server receives a connection request, it can complete the connection by accepting the request. Use the function `accepts' to do this. A socket that has been established as a server can accept connection requests from multiple clients. The server's original socket _does not become part of the connection_; instead, `accept' makes a new socket which participates in the connection. `accept' returns the descriptor for this socket. The server's original socket remains available for listening for further connection requests. The number of pending connection requests on a server socket is finite. If connection requests arrive from clients faster than the server can act upon them, the queue can fill up and additional requests are refused with an `ECONNREFUSED' error. You can specify the maximum length of this queue as an argument to the `listen functions, although the system may also impose its own internal limit on the length of this queue. Function: int accept (int SOCKET, struct sockaddr *ADDR, socklen_*LENGTH_PTR) This function is used to accept a connection request on the server socket SOCKET. The `accept' function waits if there are no connections pending, unless the socket SOCKET has nonblocking mode set. (You can use `select' to wait for a pending connection, with a nonblocking socket.) The ADDR and LENGTH-PTR arguments are used to return information about the name of the client socket that initiated the connection SOCKET part of the connection. Instead, it creates a new socket which becomes connected. The normal return value of `accept' is the file descriptor for the new socket. Accepting a connection does not make
Feb-June-2012
12
Implementation
After `accept', the original socket SOCKET remains open and unconnected, and continues listening until you close it. You can accept further connections with SOCKET by calling `accept' again. If an error occurs, `accept' returns `-1'
Feb-June-2012
13
Probably the best approach to checking on TCP/IP is to use the netstat command, which gives many different summaries of all network connections and their status like the type of socket being used whether and connected or not..
The ping command: The ping command is used to query another system and ensure a connection is active. The ping program operates by sending a request to the destination machine for reply. If the destination machines IP software receives the request, it issues a reply immediately.
Feb-June-2012
14
Implementation
As soon as the Client is executed the list of files in the Server side and as well as the Clients side is displayed on the terminal, looking at which we can decide which to transfer from Server to Client. Now we create a status buffer to hold the status of the current transfer being done. When the Client sends send data in this buffer then the Server should be ready to send data to the Client. This transfer is done by using two buffers sandbur and recvbuf at both Server and Client end. These buffers are used in such a way that the Client reads simultaneously when the Server writes. These buffers are given an appropriate size so as not to overflow the receivers buffer. The whole process of transferring of data is done in an infinite loop at the Server side. Upon receiving this status the server then starts the transmission of file contents. The initial transfer across the Server and Client happens from the Server to Client when we are listing the contents of the Server Directory on the Client side. This is accomplished using a while ( ) loop and reading in the server directory contents through the socket. Then the client asks the user to enter the filename of the File on the server directory to be transferred. This is sent to the server the server is in the read mode i.e.; the Server reads in the filename supplied by the client. The server then opens the File in the server directory and reads into the buffer the file contents (The max. possible amount being the size of the buffer.), This is then sent to the Client which receives and writes immediately into the file and sets the status buffer to send data and ONLY then does the server send the next buffer full of data to the client. This process is repeated until the entire contents of the file are transferred to the client.
Feb-June-2012
15
Implementation
Feb-June-2012
16
Implementation
PASSWORD (PASS) The argument field is a Telnet string specifying the users password. This command must be immediately preceded by the user name command, and, for some sites, completes the user's identification for access control. Since password information is quite sensitive, it is desirable in general to "mask" it or suppress typeout. It appears that the server has no foolproof way to achieve this. It is therefore the responsibility of the user-FTP process to hide the sensitive password information. CHANGE WORKING DIRECTORY (CWD) This command allows the user to work with a different directory or dataset for file storage or retrieval without altering his login or accounting information. Transfer parameters are similarly unchanged. The argument is a pathname specifying a directory or other system dependent file group design.
Feb-June-2012
17
LOGOUT (QUIT) This command terminates a USER and if file transfer is not in progress, the server closes the control connection. If file transfer is in progress, the connection will remain open for result response and the server will then close it. If the user-process is transferring files for several USER but does not wish to close and then reopen connections for each, then the REIN command should be used instead of QUIT. An unexpected close on the control connection will cause the server to take the effective action of an abort (ABOR) and a logout (QUIT).
Implementation
STORE (STOR) This command causes the server-DTP to accept the data transferred via the data connection and to store the data as a file at the server site. If the file specified in the pathname exists at the
Feb-June-2012
18
Testing
5. TESTING
Dept. of CSE, R.V.C.E Feb-June-2012 19
Testing
Feb-June-2012
20
Testing
Remarks
Feb-June-2012
21
Feb-June-2012
22
Conclusion
6. CONCLUSION
6.1 Summary:
The project is an earnest attempt to create a network utility application that can facilitate file transferring and communication between server and client at the LAN level. The purpose of the project is to build an interface for file transfer between two or more terminals running on the same operating system. The scope of this is to have user friendly protocol at the client end that allows file transfer, changing the directory, listing files of server computer which or working on the same or different terminals(of same operating system). The project has been a great experience for both of us as such in learning the intricate details of writing code for network applications. The project also gave us an insight into the working of sockets as such and the file transfer in networking in general. It has given us lot of confidence to handle similar projects in the future.
Feb-June-2012
23
6.2 Limitations:
The ftp has the following limitations It does not provide all the ftp commands. It doesnt provide more security options
The client can delete the files on the server computer.
The client using should know the knowledge about ftp commands
Conclusion
7. REFERENCES
[1] W. Richard Stevens, Advanced Programming in the UNIX Environment, Second Edition, Addison Wesley. [2] Behrouz A. Forouzan, Data Communication and Networking, Fourth edition, TMH [3] W. Richard Stevens, Network Programming in the UNIX using sockets and TLI, Volume 1, Second Edition, Addison Wesley [4] Andrew.S.Tanenbaum,Computer Networks, Fourth Edition, prentice Hall
Feb-June-2012
24
Appendices
Feb-June-2012
25
Appendices
{
while (left) int sent = send(sockfd, str, left, 0); if (sent == -1) { perror("send error"); exit(1); } left -= sent; str += sent; }
Feb-June-2012
26
Appendices
}
ptr += len; } exit(1); } void print_all_that_you_can_read(FILE *write_to, int read_from_socket_fd) { char buffer[BUFLEN]; int len = 0; while ((len = recv(read_from_socket_fd, buffer, BUFLEN, 0)) != 0) { buffer[len] = '\0'; fputs(buffer, write_to); } fflush(stdout);
Feb-June-2012
27
Server:
#include "common.h" #define SERVER_PORT 1234 #define LISTEN_SIZE 5 #define DATA_PORT_RANGE_START 20000 #define DATA_PORT_RANGE_END 20100 static const char* HELLO_MSG = "220 Welcome to my FTP server\r\n"; static char *CONTEXT = "parent";
Appendices
// FTP passive mode implementation related info int data_port_open = 0; int data_port_fd = 0; int next_data_port = DATA_PORT_RANGE_START; // Type: ASCII (A) or Binary (I) char transfer_type = 'A'; int init_server(); void handle_client_connection(int clientfd, char* client_ip, int client_port); void handle_retr(int clientfd, const char*); void handle_auth(int clientfd); void handle_put(int clientfd, const char*); void handle_list(int clientfd); void handle_pwd(int clientfd); void handle_cwd(int clientfd, const char*);
Feb-June-2012
28
Feb-June-2012
29
set_my_server_ip(); serverfd = init_server(); if (serverfd == -1) { logmsg("Initializing server failed\n"); exit(1); } while (1) { logmsg("Waiting for client connection...\n"); clientinfolen = sizeof(clientinfo); clientfd = accept(serverfd, (struct sockaddr *)&clientinfo, &clientinfolen); if (clientfd == -1) { perror("accept"); exit(1);
Appendices
}
ret = inet_ntop(AF_INET, &(clientinfo.sin_addr), client_ip, sizeof(client_ip)); if (ret == 0) { perror("inet_ntop"); } client_port = ntohs(clientinfo.sin_port); logmsg("Got connection from client IP=%s port=%d\n", client_ip, client_port); pid = fork(); if (pid == -1) { perror("fork"); exit(1); } else if (pid != 0) { // Parent
Feb-June-2012
30
Appendices
sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd == -1) { perror("socket"); logmsg("Error creating socket\n"); return -1; } if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { perror("setsockopt"); exit(1); } memset(&servinfo, 0, sizeof(servinfo)); servinfo.sin_family = AF_INET; servinfo.sin_port = htons(SERVER_PORT); servinfo.sin_addr.s_addr = INADDR_ANY;
Feb-June-2012
31
res = bind(sockfd, (struct sockaddr*)&servinfo, sizeof (servinfo)); if (res == -1) { perror("bind"); return -1; } logmsg("Server listening on port %d\n", SERVER_PORT); res = listen(sockfd, LISTEN_SIZE); if (res == -1) { perror("listen"); return -1; }
Appendices
}
return sockfd;
int open_data_port(int *port) { int fd = socket(AF_INET, SOCK_STREAM, 0); int p = 0; int ret = 0; int yes = 1; struct sockaddr_in datasock; if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { perror("setsockopt"); exit(1); } memset(&datasock, 0, sizeof(datasock));
Feb-June-2012
32
Feb-June-2012
33
void process_request (int clientfd, const char* cmd, const char* args) { logmsg("Command = %s Args = %s\n", cmd, args); if (strcmp(cmd, "AUTH") == 0) { handle_auth(clientfd); } else if (strcmp(cmd, "USER") == 0) { handle_user(clientfd, args); } else if (strcmp(cmd, "TYPE") == 0) { handle_type(clientfd, args);
Appendices
} {
else if (strcmp(cmd, "PASS") == 0) handle_pass(clientfd, args); } else if (strcmp(cmd, "RETR") == 0) { handle_retr (clientfd, args); } else if (strcmp(cmd, "STOR") == 0) { handle_put (clientfd, args); } else if (strcmp(cmd, "LIST") == 0) { handle_list (clientfd);
Feb-June-2012
34
Appendices
handle_pasv (clientfd);
Feb-June-2012
35
Appendices
sendstring (clientfd, "421 File delete error\r\n"); logmsg ("File delete %s failed", args);
} } void handle_auth (int clientfd) { sendstring (clientfd, "530 User name and pass\r\n"); } void handle_user (int clientfd, const char* args) { if(strncmp(args, "ftp", 3) == 0) { sendstring (clientfd, "331 Enter password\r\n"); }
Feb-June-2012
36
Appendices
} }
void handle_type (int clientfd, const char* args) { if (args[0] == 'A') { transfer_type = args[0]; sendstring (clientfd, "200 Switching to ASCII mode\r\n"); } else if (args[0] == 'I') { transfer_type = args[0]; sendstring (clientfd, "200 Switching to Binary mode\r\n"); } } void handle_pasv (int clientfd) {
Feb-June-2012
37
Appendices
}
void str_replace(char *str, char c, char replacechar) { char *ptr = str; for (ptr = str; *ptr != '\0'; ptr++) { if (*ptr == c) { *ptr = replacechar; } } } void handle_list (int clientfd) { struct sockaddr_in clientinfo;
Feb-June-2012
38
Appendices
Feb-June-2012
39
Appendices
Feb-June-2012
40
Appendices
Feb-June-2012
41
Appendices
Feb-June-2012
42
logmsg("Waiting for client connection\n"); fd = accept(data_port_fd, (struct sockaddr *)&clientinfo, &len); if (fd == -1) { perror("accept"); exit (1); } logmsg("Client connected\n");
Appendices
fp = fopen (args, "w"); if (fp == NULL) { logmsg("File open failed: %s\n", args); sendstring(clientfd, "555 Failed to open file.\r\n"); close(fd); shutdown(fd, SHUT_RDWR); return; } printf("%s this is the file\n", args); print_all_that_you_can_read(fp, fd); sendstring(clientfd, "231 Successfully sent to server\r\n"); fclose(fp); close(fd); shutdown(fd, SHUT_RDWR);
Feb-June-2012
43
return; } void handle_client_connection(int clientfd, char* client_ip, int client_port) { char buf[BUFLEN] = ""; char* ptr = buf; char* cmd = ""; char* args = ""; char* context = malloc (BUFLEN); snprintf (context, BUFLEN, "Child[%s:%d] ", client_ip, client_port); CONTEXT Appendices = context; logmsg ("Sending hello msg\n"); sendstring (clientfd, HELLO_MSG); while(1) { int argslen; readline (clientfd, buf, sizeof(buf)); logmsg ("Client says: %s", buf); ptr = buf; cmd = strsep(&ptr, " \r\n"); args = ptr; argslen = strlen(args); if (argslen > 0 && args[argslen-1] == '\n') { args[argslen-1] = '\0'; }
Feb-June-2012
44
Client:
#include "common.h" #define BUFLEN 100 int sockfd = -1; int is_connected = 0, is_user = 0, is_verified = 0; int clientfd = -1; char* server_ip; void process_command (const char*,char*); int turn_passive(); int make_connection(char* ip, int port) { struct sockaddr_in serverinfo; int res; socklen_t len; int fd = socket (AF_INET, SOCK_STREAM, 0); if (fd == -1) { printf("socket not created\n"); exit(1); }
Appendices
Feb-June-2012
45
Appendices
int server_port; char buffer[BUFLEN]; server_ip = strdup(strsep (&args, " \r\n")); printf ("%s", args); server_port = atoi(args); printf("Server ip is %s port is %d\n", server_ip, server_port); clientfd = make_connection(server_ip, server_port); is_connected = 1; readline (clientfd, buffer, BUFLEN); printf("%s", buffer );
} void send_to_server(const char* cmd, const char* args) { int len = strlen(cmd) + strlen(" ") + strlen(args) + 3;
Feb-June-2012
46
Appendices
if (serverfd < 0) return; remote_file = strsep(&args, " "); local_file = args; if (local_file[strlen(local_file) - 1] == '\n') local_file[strlen(local_file) - 1] = '\0'; send_to_server("RETR", remote_file); readline(clientfd, buffer, BUFLEN); if (strncmp(buffer, "550", 3) == 0) { printf("%s", buffer); shutdown(serverfd, SHUT_RDWR); close(serverfd); return; } output = fopen(local_file, "w");
Feb-June-2012
47
Appendices
{
void handle_put (char* args) char buf[BUFLEN]; char buffer[BUFLEN]; char* remote_file = NULL, *local_file = NULL; char * ptr; FILE *output = NULL; int i; int serverfd = turn_passive(); if (serverfd < 0) return; local_file = strsep(&args, " ");
Feb-June-2012
48
output = fopen(local_file, "r"); if (output == NULL) { printf("Failed to open local file: %s\n", local_file); shutdown(serverfd, SHUT_RDWR); close(serverfd); return; }
Appendices
sendstring(clientfd, buffer); if (strncmp(buffer, "555", 3) == 0) { printf("%s", buffer); shutdown(serverfd, SHUT_RDWR); close(serverfd); return; }
while ((ptr = fgets(buf, BUFLEN-1, output))) { int buflen = strlen(buf); if (buflen > 0 && buf[buflen-1] == '\n') { buf[buflen-1] = '\r'; buf[buflen] = '\n'; buf[buflen+1] = '\0';
Feb-June-2012
49
readline(clientfd, buffer, BUFLEN); printf("%s", buffer); } void handle_list() { char buffer[BUFLEN]; int serverfd = turn_passive(); if (serverfd < 0) return; sendstring(clientfd, "LIST\r\n"); readline(clientfd, buffer, BUFLEN); print_all_that_you_can_read(stdout, serverfd); readline(clientfd, buffer, BUFLEN); printf("%s", buffer); shutdown(serverfd, SHUT_RDWR); close(serverfd); } char *read_ip(char **buf) {
Appendices
Feb-June-2012
50
Feb-June-2012
51
Appendices
}
void process_command(const char* cmd, char* args) { char buffer[BUFLEN]; if (strcmp (cmd, "open") == 0) { printf("Opening\n"); open_connection(args); } {
Appendices
if(strcmp (cmd, "user") == 0) { send_to_server("USER", args); readline(clientfd, buffer, BUFLEN); printf("%s", buffer); if(strncmp(buffer, "331", 3) == 0) { is_user = 1; }
Feb-June-2012
52
Appendices
Feb-June-2012
53
Appendices
Feb-June-2012
54
Appendices
} int main() { char* ptr; char line[BUFLEN]; const char* cmd; char* args; printf("ftp> "); while((ptr = fgets(line, BUFLEN, stdin)) != NULL) { cmd = strsep (&ptr, " "); args = ptr; process_command (cmd, args); printf ("ftp> "); }
Feb-June-2012
55
Appendices
APPENDIX B SNAPSHOTS
Feb-June-2012
56
Feb-June-2012
57
Feb-June-2012
58
Appendices
Feb-June-2012
59
Feb-June-2012
60
Appendices
Feb-June-2012
61
Feb-June-2012
62
Appendices
Feb-June-2012
63
Feb-June-2012
64
Appendices
Feb-June-2012
65
Feb-June-2012
66
Appendices
Feb-June-2012
67