Как я могу сопоставить локальный сокет unix с сокетом inet?

Мне любопытно, возможно ли сопоставить сокет UNIX с сокетом INET. Ситуация просто в том, что я хотел бы подключиться к серверу MySQL. К сожалению, у него отключены сокеты INET, и поэтому я могу подключаться только к сокетам UNIX. Инструменты, которые я использую/пишу, должны подключаться к сокету INET, поэтому я пытаюсь посмотреть, смогу ли я сопоставить один с другим.

Потребовалось немало поисков, но я нашел socat, который якобы делает то, что я м ищу. Мне было интересно, есть ли у кого-нибудь предложения о том, как это сделать. Командная строка, которую я использовал (с частичным успехом):

socat -v UNIX-CONNECT:/var/lib/mysql/mysql.sock TCP-LISTEN:6666,reuseaddr

Теперь я могу подключаться и разговаривать с сервером. К сожалению, любые попытки создания нескольких соединений терпят неудачу, так как мне нужно использовать опцию fork, но эта опция, похоже, делает соединения нефункциональными.

Я знаю, что могу решить эту проблему с помощью Perl (я предпочитаю язык), но я бы предпочел не писать всю реализацию самостоятельно. Я знаком с библиотеками IO::Socket, я просто надеюсь, что у кого-нибудь есть опыт в подобных вещах. Открыт для предложений/идей.

Спасибо.


person Danny    schedule 21.05.2009    source источник


Ответы (3)


Измените порядок ваших аргументов на socat, и это сработает.

socat -v tcp-l:6666,reuseaddr,fork unix:/var/lib/mysql/mysql.sock

Это указывает socat на

  1. Слушайте TCP-порт 6666 (с SO_REUSEADDR)
  2. Подождите, чтобы принять соединение
  3. Когда соединение установлено, fork. В ребенке продолжайте шаги, описанные ниже. В родительском перейдите к 2.
  4. Откройте соединение домена UNIX с сокетом /var/lib/mysql/mysql.sock.
  5. Передайте данные между двумя конечными точками, затем выйдите.

Пишешь наоборот

socat -v unix:/var/lib/mysql/mysql.sock tcp-l:6666,reuseaddr,fork

не работает, потому что это указывает socat на

  1. Откройте соединение домена UNIX с сокетом /var/lib/mysql/mysql.sock.
  2. Слушайте TCP-порт 6666 (с SO_REUSEADDR)
  3. Подождите, чтобы принять соединение
  4. Когда соединение установлено, создайте дочерний рабочий процесс для передачи данных между двумя адресами.
  5. Родитель продолжает принимать соединения по второму адресу, но первый адрес больше не доступен: он был предоставлен первому потомку. Так что с этого момента ничего полезного сделать нельзя.
person ephemient    schedule 21.05.2009
comment
Спасибо, это именно то, что я искал. Удивительно, какая это была глупая ошибка. - person Danny; 22.05.2009

Да, вы можете сделать это в Perl.

Посмотрите на perlipc, IO::Select, IO ::Socket и Руководство Beej по сетевому программированию.

person daotoad    schedule 21.05.2009

Возможно, вы захотите сделать это в POE — это асинхронная библиотека для обработки событий, поэтому она отлично подходит для этой задачи.

Это не на 100% актуально, но я использую POE для написания прокси между протоколом без сохранения состояния (HTTP) и протоколом с сохранением состояния (сеанс telnet, а точнее - сеанс MUD), и это было довольно просто - вы можете проверить код здесь: http://www.depesz.com/index.php/2009/04/08/learning-poe-http-2-mud-proxy/.

В комментариях кто-то также предложил Coro/AnyEvent — я еще не играл с ним, но вы можете проверить.

person Community    schedule 21.05.2009