Полная история «Это зависит от того, что вы имеете в виду». Если вы хотите прослушать тот же IP-адрес и порт в качестве существующей программы, которую у вас нет контроля, то, как указывали другие, вы можете быть удачи. Однако, если вы:
, тогда вас могут быть заинтересованы в остальной части этого поста.
, когда программа использует системный вызов , чтобы назначить адрес в сокет, что Adddress (в случае af_inet Разъем) Определяет как порт, так и IP-адрес. Таким образом, два адреса с одним и тем же портом, но разные IP-адреса различны и могут быть назначены отдельно без конфликтов. Например, использование SOCAT Я могу привязать к порту 9000 на IP-адресе для моего интерфейса обратной связи в одной оболочке:
socat TCP4-LISTEN:9000,bind=127.0.0.1 STDOUT
и связываться с одним и тем же портом, но на моем внешнем IP-адресе в другом:
socat TCP4-LISTEN:9000,bind=10.0.2.15 STDOUT
Оба процесса могут принимать соединения, которые входят в IP-адрес и порт, на которых они слушают. Обратите внимание, однако, что если кто-то слушает на адрес WildCar 0.0.0.0, то вы не можете связываться с более конкретным адресом, поскольку первый процесс связан с каждым IP-адресом в системе.
по умолчанию, два процесса не могут связывать два разных файловых дескриптора одинаковым адресом. В Linux, пытаясь сделать это приведет к возвращению EADDDrinuse из Bind (2)
:
socat TCP4-LISTEN:9000,bind=127.0.0.1 STDOUT
2014/11/07 00:10:13 socat[21202] E bind(3, {AF=2 127.0.0.1:9000}, 16): Address already in use
Учитывая ваш вопрос и следствие, я догадаюсь, что у вас нет большого контроля над программой, использующей в настоящее время Ваш желаемый порт. Если вы это сделали, можно использовать один процесс, чтобы иметь установленное соединение на порту + iPaddress, а другой прослушивает один и тот же адрес. Например, многие серверные приложения делают следующее:
В этом случае вы увидите детский процесс с установленным соединением в порту и родительский процесс с разъемом прослушивания на одном порту.
В очень недавних ядрах Linux можно использовать два совершенно неродных процесса для оба связывания к одному и тому же адресу, используя опцию сокета SO_REUSEPORT. Если процессы устанавливают опцию SO_REUSEPORT на розетке, то другие процессы с тем же эффективным UID первого процесса также могут установить опцию SO_REUSEPORT и связываться с тем же адресом.
К сожалению, моя версия Сокат
, кажется, есть ошибка, которая делает его трудно дать простой пример TCP; Тем не менее, я предоставил короткий и плохо письменный пример программы ниже. Если вы запустите эту программу в качестве одного и того же пользователя в двух разных оболочках, оба будут связываться () без проблемы:
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 127.0.0.1:9000 *:* users:(("bind_tcp_reusep",pid=21254,fd=3))
LISTEN 0 128 127.0.0.1:9000 *:* users:(("bind_tcp_reusep",pid=21253,fd=3))
Целью этого состоит в том, чтобы дать людям, написание сетевых серверов нового инструмента для создания приложений, которые могут обрабатывать большое количество одновременные соединения.
Следующая статья LWN имеет хороший обзор случая использования для этой опции:
http://lwn.net/articles/542629/
, как упомянул ROBBAT2, Если вы хотите шпионить на существующем трафике TCPDUMP
- лучший ставка.
#include
#include
#include
#include
#include
#include
#include
#include
int main() {
struct sockaddr_in bind_addr;
struct sockaddr peer_addr;
int optval = 1;
int tcp_socket;
int err;
int addr_len = sizeof(struct sockaddr);
memset(&bind_addr, 0, sizeof(struct sockaddr_in));
memset(&peer_addr, 0, sizeof(struct sockaddr));
bind_addr.sin_family = AF_INET;
bind_addr.sin_port = htons(9000);
if (inet_pton(AF_INET, "127.0.0.1", &(bind_addr.sin_addr)) != 1) {
perror("inet_pton");
exit(1);
}
tcp_socket = socket(AF_INET, SOCK_STREAM, 0);
setsockopt(tcp_socket, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval));
err = bind(tcp_socket, (const struct sockaddr *)&bind_addr, sizeof(struct sockaddr));
if (err != 0) {
perror("bind failed");
exit(1);
}
err = listen(tcp_socket, 256);
if (err != 0) {
perror("listen failed");
exit(1);
}
accept(tcp_socket, &peer_addr, &addr_len);
}
Если вы хотите избежать этого, то вам нужна новая цепочка:
iptables -N sshgroup1
# or reset with iptables -F sshgroup1 if it already exists
iptables -t filter -A ssh -s 10.10.10.10/32 -m mac \
--mac-source 10:10:10:10:10:10 -j sshgroup1
iptables -t filter -A sshgroup1 ... -j ACCEPT
iptables -t filter -A sshgroup1 ... -j ACCEPT
Если вы хотите разрешить ssh соединения только с двух хостов в вашей локальной сети, то вы должны держать эти правила наверху, чтобы iptables работал быстрее.
iptables -I INPUT -p tcp -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -I INPUT -p tcp --dport 22 -s 10.10.10.10/32 -m mac --mac-source 10:10:10:10:10:10 -j ACCEPT
iptables -I INPUT -p tcp --dport 22 -s 11.11.11.11/32 -m mac --mac-source 11:11:11:11:11:11 -j ACCEPT
Иначе есть много комбинаций, зависящих от вашей сети, политик и трафика.
Эмпирическое правило таково: Постарайтесь избегать повторения правил и минимизируйте уровень совпадения для более быстрой работы
.