2017-05-21 1 views
0

J'ai regardé autour sans succès sur comment faire pour que le client reçoive des demandes du serveur sans bloquer la boucle principale, je m'excuse s'il y a un double là-bas, mais tout ce que j'ai trouvé en ligne sont des versions de TCP, qui ne fonctionnent pas pour mon but (UDP). En ce moment, le serveur est juste un serveur Echo, donc je m'en fous si ça bloque.C Socket UDP non bloquante

Le serveur est créé comme suit

ServerInstance Init(ServerConfiguration c) { 
    ServerInstance n; 
    n.endpoint = socket(PF_INET, SOCK_DGRAM, 0); 
    Exitif(n.endpoint < 0, "Error opening endpoint socket"); 
    setsockopt(n.endpoint, SOL_SOCKET, SO_REUSEADDR, (const void *) &c.trueval, sizeof(int)); 
    setzero((char *) &n.servaddr, sizeof(n.servaddr)); 
    n.servaddr.sin_family = AF_INET; 
    n.servaddr.sin_addr.s_addr = htonl(INADDR_ANY); 
    n.servaddr.sin_port = htons(c.portno); 
    Exitif(bind(n.endpoint, (struct sockaddr *) &n.servaddr, sizeof(n.servaddr)) < 0, 
    "Error on binding socket to addr"); 
    n.buf = calloc(c.buffersize, sizeof(char)) 
    return n; 
} 

En ce qui concerne le client:

connection = socket(AF_INET, SOCK_DGRAM, 0); 
    IfThenExit(socket < 0, "Error initializing UDP socket\n"); 
    setzero((char *) &servaddr, sizeof(servaddr)); 
    servaddr.sin_family = AF_INET; 
    servaddr.sin_port = htons(PORT); 
    IfThenExit(inet_aton(SRVADDR, &servaddr.sin_addr) == 0, "IPV4 Address Invalid\n"); 
    CleanQueueAdd(&connection, Socket); 

Et des boucles comme ci-dessus, j'ai aussi piscine d'événements de SDL, et je voudrais savoir comment je peux mettre en œuvre quelque chose comme ça sans bloquer le programme

if(1) { 
    while(SDL_PollEvent(&e)) { 
    switch(e.type) { 
     case SDL_QUIT: 
     quit = 1; 
     break; 
     case SDL_KEYDOWN: 
     quit = 1; 
     break; 
    } 
    } 
    // Recv here blocks ... 
    // recv(...) 
} 

Merci d'avoir lu et d'avoir un nice day

+1

Quel est le protocole utilisé par la connexion réseau utilisée par les références de socket n'a aucun effet sur la façon de définir un socket non bloquant et de l'utiliser. L'interface de socket est indépendante du protocole réseau. –

+0

Vous avez deux options. Je m'attends à voir un code qui 1/définit le mode socket à non bloquant, ou 2/appelle des fonctions de socket en utilisant des options pour spécifier des appels non bloquants ... mais je ne vois aucun de ces deux ... et donc je vote fermer. – Sebivor

+0

@Seb J'ai mis le socket en mode non-bloquant après avoir posé cette question, mais est-ce optimal par rapport à poll ou select? Je lis les cycles CPU gaspillés – Whiteclaws

Répondre

0

Il semble que les événements SDL ne peuvent pas être multiplexés avec des événements arbitraires non-SDL. Au lieu de cela, vous pouvez créer un thread secondaire qui utilise select() ou epoll() ou un wrapper autour de ceux-ci. Ce thread attendra les messages réseau, les lira et les analysera peut-être, et transmettra les requêtes au thread principal en utilisant SDL_PushEvent.

+0

Non, je ne veux pas pousser les événements dans la file d'attente SDL, mais plutôt trouver un moyen d'interroger les événements d'une manière non bloquante - tout comme SDL avec SDL_PollEvent, Existe-t-il des exemples autour du net sur comment implémenter cela avec un sondage ou sélectionner? Pas de multi-threading si possible, je veux appeler recv et retourner immédiatement s'il n'y a pas de paquets en attente de lecture – Whiteclaws

+0

@Whiteclaws: Vous pouvez trouver des milliers d'exemples de multiplexage d'E/S en utilisant select() sur les sockets, mais alors comment allez-vous vérifier les événements SDL? Si vous avez vraiment besoin de vérifier les événements SDL et aussi les événements de socket, vous devrez peut-être effectuer des interrogations actives ou en attente: vérifiez la socket pour les données, vérifiez la file d'attente SDL pour les événements, dormez un moment et répétez. Ce processus sera inefficace mais permettra l'utilisation d'un seul thread. –

+0

Ni 'select' ni' epoll' ne sont exclusivement bloquants; selon [le manuel pour l'ancien] (http://pubs.opengroup.org/onlinepubs/7908799/xsh/select.html), * "...' select() 'blocs, jusqu'à l'intervalle de délai spécifié, jusqu'à ce que la condition spécifiée soit vraie pour au moins l'un des descripteurs de fichiers spécifiés "*, et que ce dernier soit * E/S asynchrones * (ce qui est différent des E/S non bloquantes). – Sebivor