Monday, September 8, 2014

Dummy FTP server in C++ with Boost library

I needed to have a dummy FTP server that doesn't do any file transportation but takes user id and user password data. This is a part of porting another project of mine, Foscam IP camera utility. I think the script version was too unstable and hard to read. I ported it in C++, which looks much easier to read and reliable.

The indentation may look strange but I didn't want to have one extra indentation only for the namespace. I needed to have the namespace because I wanted to limit the "using" keywords in the scope; I wish I can put it inside of "class" like enum or typedef.

The class is to create a network server with boost library and get the FTP login information. As soon as the function, wait, ends, the socket will be destroyed and the connection will be lost.

  • The object asio::io_service is always required whenever I use boost::asio classes.
  • The object tcp::acceptor is for accepting client network connection as a server. This creates the socket for the connection. In this program, it is all synchronized and it handles only one client at the time, which is enough for my project and makes it easier to read.
  • Once the socket is created, it can be used for reading and writing with socket::read_some() and asio::write() respectively.
  • The function, asio::buffer, is something I don't fully understand but it seems to be a wrapping safety class to prevent buffer-over-flow.

I made function, readExpectedLine, that reads network input. As usual, writing to a socket is always easier because we know the length of data we want to send. When we read data from network socket, it involves complexity of size calculation, buffer overflow, connection lost and garbage input.

It throws a custom exception class, NetworkError, which inherits from std::runtime_error. I needed because the server shouldn't just throw an exception and die. The server should be more stable on exceptional cases. By having a custom exception, I can catch it and run it for the next connection.

The combination of "for" and "try-catch" may look strange. But I thought that it feels interesting. I don't like the fact that "try" takes whole line without anything with it. I feel the same for the "do-while"; do takes up the whole line with nothing on the right side. They feel like waste of the space.

The important part of the implementation in the function, main, is that it loops until it gets the data we want. It wouldn't just throw exception when garbage network input is given.

Once it got the right login information it will print out and quit.

The screenshots above shows the server side and client side respectively.

Note that when I gave garbage input, the server disconnected the client and ran for the next client without exceptions.

No comments:

Post a Comment

About Me

My photo
Tomorrow may not come, so I want to do my best now.