问题
When a client try to connect to a server, if client and server are both localhost, self-connection may happen(source port and destination port happened to be the same.). But my problem is, client is not listening to that port, how can self-connection be possible?
回答1:
I found your question after encountering the same phenomenon. The best explanation I found is at Everything About Nothing: TCP Client Self Connect.
You can ask for the port assigned to you via getsockname() and compare it to the remote port to detect these self connections:
sockaddr_in addr_client;
socklet_t len = sizeof(saddr_in);
if(getsockname(sock_client, (struct sockaddr *)&addr_client, &len))
{ /* error */ }
if(len != sizeof(saddr_in)))
{ /* error */ }
if(addr_client.sin_port == addr_server.sin_port &&
addr_client.sin_addr.s_addr == addr_server.addr.sin_addr.s_addr)
{ /* self-connection detected! */ }
回答2:
The server and client in localhost don't use the same port.
As a connected Tcp connection,
To server,source port is A and destination port is B.
To client,source port is B and destination port is A.
A is set by bind() in server, and is known to all clinets; B is usually assigned by clinets' kernel, and is known to server when the server's accept() returns.
In details:
In tcp,the server's port is set by bind() which lets us specify a port number, an IP address, both, or neither, but it is rare for a TCP server to let the kernel choose an ephemeral port Afterwards, server listen() the port and IP address.
and client uses connect() whose socket address structure must contain the IP address and port number of the server. the kernel will choose both an ephemeral port and the source IP address if necessary. Anyway, it can't be the port your server using.
That's to say, the ports of a server and a clinet in the same computer is not the same.
For example, when simple C/S programs running in a localhost, typing netstat -t in terminal,and you will get:
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 localhost:41742 localhost:9877 ESTABLISHED
tcp 0 0 localhost:9877 localhost:41742 ESTABLISHED
the prots is obviously different.
If you force the client to use the same port of your the one server is using on local by bind(), the bind() will return -1 as a error.
回答3:
We can simple reproduce this phenomenon with the following python program
import socket
for i in range(65536):
try:
s = socket.create_connection(('127.0.0.1', 50000))
print 'connected to {0}'.format(s.getpeername())
except Exception as e:
pass
when we try to connect some socket in the same host. if we don't bind your client to a specific port, operating system will provide ephemeral port
for you. if it's happened to be the one you want to connect to. it causes self connection. Make sure the port you are trying to connect is in /proc/sys/net/ipv4/ip_local_port_range
来源:https://stackoverflow.com/questions/16767113/linux-unix-socket-self-connection