(Как) Могу ли я определить семейство сокетов из дескриптора файла сокета - PullRequest
6 голосов
/ 04 февраля 2009

Я пишу API, который включает функции IPC, которые отправляют данные в другой процесс, который может быть локальным или на другом хосте. Мне бы очень хотелось, чтобы функция отправки была такой простой, как:

int mySendFunc(myDataThing_t* thing, int sd);

без вызова вызывающей стороны - в непосредственном контексте вызова mySendFunc () - приводит ли sd к локальному или удаленному процессу. Мне кажется, что если бы я мог так что-то вроде:

switch (socketFamily(sd)) {
case AF_UNIX:
case AF_LOCAL:
   // Send without byteswapping
   break;
default:
   // Use htons() and htonl() on multi-byte values
   break;
}

Было предложено реализовать socketFamily () как:

unsigned short socketFamily(int sd)
{
   struct sockaddr sa;
   size_t len;
   getsockname(sd, &sa, &len);   
   return sa.sa_family;
}

Но я немного обеспокоен эффективностью getsockname () и задаюсь вопросом, могу ли я позволить себе делать это каждый раз, когда отправляю.

Ответы [ 3 ]

6 голосов
/ 05 февраля 2009

См. getsockname (2) . Затем вы проверяете struct sockaddr на наличие семейства.

РЕДАКТИРОВАТЬ: Как примечание, иногда полезно также запросить info , в данном случае info libc sockets

EDIT:

Вы действительно не можете знать, не смотря на это каждый раз. Его нельзя просто кэшировать, так как номер сокета можно использовать повторно, закрыв и снова открыв его. Я только что заглянул в код glibc, и кажется, что getsockname - это просто системный вызов, что может негативно сказаться на производительности.

Но я предлагаю использовать некие объектно-ориентированные концепции. Заставьте пользователя передать указатель на структуру, которую вы ему ранее вернули, то есть попросите его зарегистрировать / открыть сокеты с помощью вашего API. Затем вы можете кэшировать все, что хотите об этом сокете.

2 голосов
/ 05 февраля 2009

Почему не всегда отправлять в сетевом порядке байтов?

1 голос
/ 05 февраля 2009

Если вы контролируете код клиента и сервера, у меня есть другое предложение, которое я успешно использовал в прошлом.

Пусть первые четыре байта вашего сообщения будут известным целочисленным значением. Затем получатель может проверить первые четыре байта, чтобы увидеть, соответствует ли он известному значению. Если он совпадает, то замена байтов не требуется.

Это избавляет вас от необходимости перестановки байтов, когда обе машины имеют одинаковый порядок байтов.

...