include "cs4410.php"; classheader('MiniProject: Mail Server'); leftside(); ?>
The client and the server code provided in the handout are skeletal -- they do not implement the complete protocol or even correctly implement part of the protocol (if they did, there'd be little for you to do!). In particular, the server just closes the socket immediately when it receives a new connection, and the client blindly sends data to the server without checking to see if the server sent "200 OK" responses. You are expected to not only change both the server and the client to correctly follow the amended protocol described in the project, but also to develop additional clients to test corner cases in your server implementation. In particular, you might need test clients that misbehave.
The communication between the client and server occurs over TCP. While TCP guarantees reliable delivery, it does not necessarily guarantee that data sent at the same time on the client will be received at the same time on the server (and vice versa). For instance, if the client sends the string "HELO abc12\n", the string can be chopped into three packets delivered separately at the servers, containing "HE", "LO ", and "abc12\n". You will most likely want to write a "collect_input" function that performs recv() operations in a loop until a whole message has been received, instead of trying to parse the first packet (containing only "HE") received.
A misbehaving client may send a bad command, and your
server should deal with this by returning a response
with a "500" status code. Your server should not close
the socket, but instead resume the conversation from
where it left off, thus providing the client a chance
to recover from its mistake. So the following is a
legal conversation that should be allowed by your
implementation:
HELO foo
200 HELO abc123
MAIL FROM: notice_the_space @foo.com
500 ERROR in senderemail
XXXXXXX
500 BAD COMMAND
MAIL FROM: abc@example.com
200 OK
YYYYYZZZZ
500 BAD COMMAND
RCPT TO: xyz@example.com
200 OK
In essence, you are implementing a very simple state machine whose
job is to first collect the sender email, then the receiver email,
and then the message.
As with all network protocols, you must code defensively and do something reasonable even in the presence of bad inputs. Part of the assignment is to decide what is reasonable. If you find yourself stuck, feel free to consult course staff.
Because of the way the filesystem is structured and because of the sector-based atomicity of file writes, you may not easily notice an interleaving of messages, even if you neglect to perform your file operations without any synchronization. If you write a proper test client that writes large messages, however, you should be able to see that concurrent accesses to a file without a lock can cause messages to be interleaved. You should perform your file operations as part of a critical section to avoid such interleavings.
Your code will be evaluated not only for correctness but for elegance, maintainability, and the thoroughness of accompanying test code.