J'ai une boucle while(1)
qui utilise recvfrom
pour obtenir des données qui ont été envoyées à un socket de domaine à partir d'un autre processus (P2). La boucle while doit faire 2 choses, d'abord écouter les données entrantes de P2, et ensuite exécuter une autre fonction checkVoltage()
.La fonction `recvfrom` peut-elle être utilisée pour vérifier si des données précédentes ont été envoyées à une socket? Ou faut-il écouter activement?
Il court un petit quelque chose comme ceci:
while(true)
{
listenOnSocket() /*listens for 100 u seconds*/
checkVoltage();
}
Ma question est la suivante: la fonction listenOnSocket()
utilise la fonction recvfrom
pour vérifier une entrée d'un autre processus. Il passe 100usecs à l'écoute, puis expire et continue à exécuter la fonction checkVoltage()
. Donc, il passe 99% du temps dans la fonction listenOnSocket()
. Mon problème est que si P2 envoie des informations à la socket pendant la fonction checkVoltage()
, il en résultera une erreur, indiquant: sending datagram message: No such file or directory
.
Existe-t-il un moyen de faire vérifier par cette boucle si des données ont déjà été envoyées au socket? De cette façon, si P2 envoie des données pendant la fonction checkVoltage()
, cela n'entraînera pas d'erreur.
Merci.
EDIT:
Ainsi, la fonction crée listenOnSocket()
une prise avec le nom FireControl
quand je lance P1 (le programme qui reçoit des données de P2) le fichier FireControl
disparaît pour une fraction de seconde puis réapparaît. Si P2 envoie des données à P1 pendant cette courte période, il en résulte l'erreur mentionnée en haut.
Donc je suppose que cela signifie que je devrais séparer la création de la socket de la fonction recvfrom
, parce que la courte période où la nouvelle socket est créée n'existe pas - si cela a du sens.
Je suis un dope, j'aurais dû les séparer en premier lieu!
EDIT2: Voici listenOnSocket()
:
command listenOnSocket(int timeout, float utimeout) /*Returns null payload when no input is detected*/
{
command payload;
int sock;
socklen_t* length;
struct sockaddr_un name;
char buf[1024];
struct timeval tv;
tv.tv_sec = timeout;
tv.tv_usec = utimeout;
/* Create socket from which to read. */
sock = socket(AF_UNIX, SOCK_DGRAM, 0);
if (sock < 0)
{
perror("opening datagram socket");
payload = nullPayload;
}
/* Create name. */
name.sun_family = AF_UNIX;
strcpy(name.sun_path, NAME);
unlink(name.sun_path);
/* Bind the UNIX domain address to the created socket */
if (bind(sock, (struct sockaddr *) &name, sizeof(struct sockaddr_un)))
{
perror("binding name to datagram socket\n");
payload = nullPayload;
}
/*Socket has been created at NAME*/
if (timeout != 0 || utimeout != 0)
{
setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval));
}
else
{
tv.tv_sec = 0;
tv.tv_usec = 0;
setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval));
}
/* Read from the socket */
if (recvfrom(sock, &payload, sizeof(command), 0, (struct sockaddr *)&name, &length) < 0) /*Less than zero results from a timeout*/
{
payload = nullPayload;
}
unlink(NAME);
return payload;
}
et la boucle est ici qu'il appelle:
while (1)
{
buffer = getADCValue();
checkVoltage();
temp = listenOnSocket(0, 100); /*Look for a new command*/
doStuffWithTempIfItHasChanged();
}
}
"envoyé à un socket de domaine" -> étant donné le tag, ai-je raison de supposer que vous voulez dire socket de domaine UNIX? – zneak
Etes-vous sûr que votre socket fonctionne?AFAIK, vous ne devriez pas avoir besoin d'être coincé dans 'recvfrom' pour un appel' send'/'sendto' de P2 pour terminer avec succès, les messages devraient être mis en file d'attente à condition que le socket existe. – zneak
@zneak oui, ceci est un socket de domaine unix (fonctionnant sur Raspbian). Les sockets fonctionnent vraiment, dans une autre section du code, j'exécute 'listenOnSocket' sans timeout, et le programme se trouve sur la fonction' recvfrom' pendant qu'il attend l'entrée. –