However I also want to get the actual (negotiated) TCP port the server is using. When I envoke getpeername from the client side I can only get the initial TCP listening port of the server (e.g. 443).
It is also 443.
ARPANET's original NCP did have a separate "negotiation" (ICP) that would move the connection to a dedicated server-side port. TCP does not. Because each connection has two port numbers (server-side and client-side), there is no need to negotiate a new server-side port because the full <src,dst> can already be used to distinguish between connections.
If you look at the raw TCP/IP packets seen in Wireshark – and compare against e.g. netstat -n on either the server or the client – you will see that all packets are sent between client_port and server:443, and therefore the getsockname/getpeername result (and the netstat output) is accurate.
The only similar cases of "new port per client" are FTP (which actually doesn't do that either; the control connection still remains on port 21, whereas the data ports correspond to brand new TCP connections) and TFTP (which is UDP and generally just weird).
As part of generating a unique IV for each connection, I am using current time and the client's source port as seeds
That's not a very good seed. Some operating systems use incremental source port numbers; if two Windows PCs connected to your server at once, they could easily both have the same timestamp and the same source port.
Use a proper CSPRNG (your cryptography library almost certainly has one) and use OS-provided randomness sources (your cryptography library will likely do so automatically), such as getentropy() or BCryptGenRandom().
At the same time, if you "do not want to transmit" the seed, then this is also not a very good seed. Computer clocks drift (even between NTP syncs) and the timestamp may differ. Networks have latency (packet delivery is non-instant) and the send & receive timestamps may differ. If you try to account for this by reducing timestamp precision, the seed will become even worse quality than it already is.
Also, many clients are behind SNAT gateways which randomize source ports, and the client won't have any way to know if its packets have been rewritten mid-flight to have a different source port, therefore the client's getsockname() and the server's getpeername() will differ. (But this has nothing to do with the 1st part of this answer; this is something that packet-rewriting gateways impose, and not something TCP does explicitly.)
stack, orsourceis, for example.