Как сделать «небрежную» розетку? - PullRequest
0 голосов
/ 18 апреля 2011

Мне нужен сокет (или другой метод IPC) со следующим поведением:

  1. Автор должен иметь возможность отправить данные в сокет без блокировки

  2. если никто не слушает, данные отбрасываются

  3. как обычно, читатель должен уметь подключить и получить эти данные

Что я сделал:

создал носок, вызвав

sock = socket (PF_LOCAL, SOCK_DGRAM, 0); //sock is an integer

связал его с

struct sockaddr_un name;
memset(&name,0,sizeof(struct sockaddr_un));
name.sun_family = AF_LOCAL;
strncpy (name.sun_path, filename, sizeof (name.sun_path)); //filename contains "/cosmos"
bind (sock, (struct sockaddr *) &name, sizeof(struct sockaddr_un));

затем сделал опрос на нем

struct pollfd pld;
pld.events = POLLOUT;
pld.fd = sock;
pld.revents=0;

//in loop
poll(&pld,1,50);
if(pld.revents & POLLOUT)
   write(fr,mydata,19);

Отслеживание выводит, что запись выполняется (многократно). Чтобы прослушать это я сделал:

struct sockaddr_un cos_name;
int cosmos;
char buffer[100];
memset(&cos_name,0,sizeof(struct sockaddr_un));
strncpy (cos_name.sun_path, COSMOS_SOCKET, sizeof (cos_name.sun_path));
memset(buffer,0,100);
cosmos = socket (PF_LOCAL, SOCK_DGRAM, 0);
//check on cosmos being 0
if (connect(cosmos,(struct sockaddr*) &cos_name, sizeof(struct sockaddr_un)) != 0)
{
    printf("Connecting failed: %s.\n",strerror(errno));
    return;
}
printf("Listening successfully started.\n");
//loop
{
    read(cosmos,buffer,100);
    printf("Recieved: %s.\n",buffer);
}

Однако «Получено ...» никогда не печатается.

Что необходимо изменить для достижения желаемой функциональности? Каким должно быть предложение в последнем цикле? (Я использую простое «запустить 1000 раз сейчас»).

Ответы [ 2 ]

8 голосов
/ 18 апреля 2011

Э-э, я думаю, вам нужно немного прочитать о UDP-сокетах.

Они без соединения. Вы просто отправляете пакеты в пункт назначения и надеетесь, что кто-то слушает.

На стороне сервера вы используете recvfrom() для чтения пакетов. Чтобы отправить пакет обратно клиенту, вы используете sendto() с struct sockaddr *src_addr, который вы передали в ваш recvfrom() (он заполнен информацией для клиента, который отправил пакет, который вы только что получили).

Клиент должен также связать порт и использовать recvfrom() для получения пакетов с сервера.

Серверная сторона:

  • порт связывания
  • чтение пакетов с recvfrom()
  • отправлять пакеты с sendto() обратно клиентам, используя информацию, возвращаемую с recvfrom()

Клиентская сторона:

  • порт привязки
  • отправка пакетов на сервер с sendto()
  • читать ответы с recvfrom()
0 голосов
/ 18 апреля 2011

Я люблю играть с розетками в интерактивной оболочке Python, это очень показательно. Посмотрите, как ваша проблема в основном решается с помощью сокетов UDP:

#-- setup receiving on client
>>> from socket import *
>>>
>>> rsock = socket(AF_INET, SOCK_DGRAM)
>>> rsock.bind(("127.0.0.1", 7888))
>>> rsock.recv(100)

Клиент блокирует ожидание данных. Хорошо, давайте отправим что-нибудь на это!

#-- server
>>> from socket import *
>>> 
>>> sock = socket(AF_INET, SOCK_DGRAM)
>>> sock2.sendto("hello", ("127.0.0.1", 7888))
5
>>>

Хорошо, сообщение отправлено. Переключитесь на клиентскую консоль и увидите 'hello'! ;) Попробуйте, это действительно весело.


Кстати, PF_INET не является обязательным, SOCK_DGRAMs работают с PF_UNIX абсолютно одинаково.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...