There is no way to know which ports are open without the remote computer knowing it. But you can determine the information without the program running on the port knowing it (i.e. without interfering with the program).
Use SYN scanning:
To establish a connection, TCP uses a three-way handshake. This can be exploited to find out if a port is open or not without the program knowing.
The handshake works as follows:
- The client performs an active open by sending a SYN to the server.
- The server replies with a SYN-ACK.
- Normally, the client sends an ACK back to the server. But this step is skipped.
SYN scan is the most popular form of
TCP scanning. Rather than use the
operating system's network functions,
the port scanner generates raw IP
packets itself, and monitors for
responses. This scan type is also
known as "half-open scanning", because
it never actually opens a full TCP
connection. The port scanner generates
a SYN packet. If the target port is
open, it will respond with a SYN-ACK
packet. The scanner host responds with
a RST packet, closing the connection
before the handshake is completed.
The use of raw networking has several
advantages, giving the scanner full
control of the packets sent and the
timeout for responses, and allowing
detailed reporting of the responses.
There is debate over which scan is
less intrusive on the target host. SYN
scan has the advantage that the
individual services never actually
receive a connection while some
services can be crashed with a connect
scan. However, the RST during the
handshake can cause problems for some
network stacks, particularly simple
devices like printers. There are no
conclusive arguments either way.
Source Wikipedia
As is mentioned below, I think nmap can do SYN scanning.
Using sockets for TCP port scanning:
One way to determine which ports are open is to open a socket to that port. Or to a different port which finds out the information for you like you mentioned.
For example from command prompt or a terminal:
telnet google.com 80
UDP Port scanning:
if a UDP packet is sent to a port that is not open, the system will respond with an ICMP port unreachable message. You can use this method to determine if a port is open or close. But the receiving program will know.