Linux/Unix Socket Self-connection

流过昼夜 提交于 2020-01-12 10:35:28

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!