You are right to generate symmetric keys at the beginning of the session. More precisely, the normal method is to generate one symmetric key (a session key), with a protocol that ensures that both parties generate the same key, so that this shared key can be used on both sides. A popular protocol for such a key exchange is Diffie-Hellman. (Despite the name, this isn't an exchange of symmetric keys: it's an exchange of DH public keys, which leads the two sides to be able to generate the same secret material.)
You don't need either party to have an asymmetric key pair to do this and establish a secure channel.
Where you do need at least one of the sides to have a private key and the other side to have the corresponding public key, is for authentication. With Diffie-Hellman, the two parties can be confident that no third party is going to breach their communication, but they cannot know the identity of the other party, so a man-in-the-middle attack is possible: all the attacker has to do is run the session start protocol with the client and the server independently, and from then on relay messages (or not).
If one of the parties isn't willing to communicate with just anyone, it must authenticate the other parties. There are two major methods to do this: with a shared secret (a password), or with public-key cryptography. Password authentication isn't straightforward because if e.g. the client sends its password to the server, this is dangerous unless the client is sure that it is communicating with the legitimate server. Otherwise, in case of a man-in-the-middle attack, the attacker would obtain the password and could send it onward to the server in order to impersonate the client.
Public key cryptography solves this problem. In order for the client to authenticate the server, the client must know the server's public key. The client can send a message that is encrypted with that public key; only the legitimate server will be able to decrypt the message. A simple protocol is for the client to send its password, plus some key material, in this encrypted message.
It is possible for both sides to use a public/private key pair. In this case, each party will have its own private key. Private keys are never shared between parties, otherwise there would be no point in not using symmetric ciphers.
- Implement what you think is a secure channel protocol.
- Once your implementation works, play with it. Describe your protocol in writing or with diagrams. Try to find a situation where your implementation breaks — where it allows a third party to eavesdrop on the communication between the client and the server, or to impersonate one of the parties, or to inject illegitimate commands or responses. Cryptography is hard, so don't be discouraged if you got it wrong — that's almost the point of the exercise.
- It is said that anyone can build a cryptographic protocol that they cannot break, if they tried hard enough. So if you can't break your own protocol, look up the literature on TLS, which is the industry standard for secure channels. Find a feature in TLS that protects against something that you don't. Figure out how to break your protocol that way.