When a TCP Server does a socket accept on a port, it gets a new socket to work with that Client.
The accepting socket remains valid for that port and can accept further clients on that port.
Why did the original FTP specification RFC 959 decide to create both a control port and a data port?
Would there be any reason to do this in a similar custom protocol?
It seems to me that this could have been easily specified on a single port.
Given all the problems with firewalls and NATS with FTP, it seems that a single port would have been much better.
For a general protocol implementation, the only reason I could think that you would want to do this is so that you can serve the files from a different host than the commands are going to.
The initial rationale behind this was so that you could:
True, they could have achieved the same result by specifying a complicated multiplexing protocol integrated to the FTP protocol, but since at that time NAT was a non issue, they chose to use what already existed, TCP ports.
Here is an example:
Alice wants two files from Bob. Alice connects to Bob port 21 and asks for the files. Bob open connections to Alice port 20 when it's ready and send the files there. Meanwhile, Charles needs a file on Alice's server. Charles connects to 21 on Alice and asks for the file. Alice connects to port 20 on Charles when ready, and sends the files.
As you can see, port 21 is for client connecting to servers and port 20 is for servers connecting to clients, but those clients could still serve files on 21.
Both ports serve a totally different purpose, and again for sake of simplicity, they chose to use two different ports instead of implementing a negotiation protocol.