Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Sockets en C++

55 réponses
Avatar
Merwin
Bonjour à tous,

Je suis étudiant en DUT Informatique, et je programme un peu en dehors
des cours pour m'entrainer, voici donc quelques questions.

1) J'aimerais faire une petite application qui se connecte à un serveur
IRC, donc via des sockets TCP. Seulement je me heurte à quelques problèmes:

- Y a t'il des bibliothèques portables qui me permettent de gérer plus
facilement les sockets? L'idée c'est que le code sois facilement
compilable d'une platforme à une autre.

Je sais que c'est possible avec Qt par exemple, mais ça me parait un peu
lourd, puisque si je commence à utiliser Qt, je vais utiliser tous
l'arsenal qui va avec (QSring, QList etc...), et je souhaiterais
utiliser un maximum la STL.

- Comment gérer le "main loop", je ne sais pas trop comment ça
fonctionne, car si je ne fais pas une boucle infinie (while true?) mon
programme arrete de s'éxécuter (normal me direz-vous...).

Alors comment puis-je empecher mon programme de s'arreter? Je cherche la
manière la plus propre possible. Encore une fois Qt permet ça facilement
puisque de base il y a un "event loop" qui gère ça, mais j'aimerais peut
voir d'autres méthodes.

2) Comment puis-je placer mon application en "fond", c'est à dire
qu'elle rende la main une fois qu'elle a été démarée. Idem, je cherche
une solution portable !

Merci d'avance pour votre aide,

Thibaut

10 réponses

1 2 3 4 5
Avatar
Merwin
Fabien LE LEZ a écrit :
On Thu, 12 Mar 2009 19:18:04 +0100, (Pascal J.
Bourguignon):

Si ton programme a des threads, tu peux ne pas avoir une boucle
d'évènement, mais juste une boucle infinie.



Utiliser des threads ici ne me paraît pas forcément la meilleure idée.
Mais même s'il utilise plusieurs threads, il y en aura bien un qui a
une boucle avec un "select" (ou équivalent).

Par ailleurs, Boost.Asio m'a l'air d'inclure la gestion d'une telle
boucle.





Je vais regarder de ce coté la, merci.
Avatar
James Kanze
On Mar 12, 7:41 pm, Fabien LE LEZ wrote:
On Thu, 12 Mar 2009 19:18:04 +0100,
(Pascal J. Bourguignon):



>Si ton programme a des threads, tu peux ne pas avoir une
>boucle d'évènement, mais juste une boucle infinie.



Utiliser des threads ici ne me paraît pas forcément la
meilleure idée. Mais même s'il utilise plusieurs threads, il
y en aura bien un qui a une boucle avec un "select" (ou
équivalent).



Pas vraiment. Je ne sais pas comment ça marche sous Windows,
mais au moins sous Unix, une fois la connexion établie, tu peux
lire et écrire le socket exactement comme un fichier. Tu crées
donc un thread par connexion (pour que l'attente sur une
connection ne bloque pas toute l'application), et ensuite, le
thread gère le socket exactement comme il ferait un fichier (ou
plutôt un tty -- les socket ne supportent pas des seek, par
exemple).

Le select, c'est utile quand tu n'as pas de threads, et que tu
veux attendre sur plusiers sockets (ou d'autres « file
descriptor », e.g. le clavier, ou un pseudo-terminal qui
représente une fenêtre sur l'écran).

Par ailleurs, Boost.Asio m'a l'air d'inclure la gestion d'une
telle boucle.



Je crois que Boost.Asio s'adresse à un autre problème, des
entrées/sorties non bloquantes. Si tu as des threads, il n'y a
pas vraiment de motif à utiliser des entrées/sorties non
bloquantes.

>Une application ne se met pas en tâche de fond normalement.



Ça dépend de ce qu'on appelle "tâche de fond".



Sous MS-DOS, ça avait un sens : c'était un bout de code qui
était appelé par le système sous certaines conditions. Par
exemple, le driver de la souris ou du lecteur CD-ROM.



Sur un OS moderne (Windows, *nix), plusieurs processus
tournent en même temps. La notion de "tâche de fond" n'a donc
plus guère de sens. Le seul truc, c'est qu'un processus peut
interagir avec une console (texte ou graphique) ou non.



Encore : sous Unix, il y a bien la notion d'un groupe de
processus, avec un terminal maître. Ou non -- si l'expression
« tache de fond » n'est pas très courant (on parle plutôt de
démon), le principe est le même -- un démon (ou une « tache de
fond »), c'est un groupe de processus (souvent un seul
processus) sans terminal maître. Alors, pour créer un démon
(démoniser le processus), il faut bien le détacher du groupe et
du terminal, et s'assurer qu'il n'y a pas de parent qui doit
l'attendre.

Mais c'est très particulier à Unix. Je ne crois pas qu'il soit
appliquable à Windows.

--
James Kanze (GABI Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Avatar
James Kanze
On Mar 13, 1:17 am, Merwin wrote:
Marc Espie a écrit :



> In article <49b93d83$0$12613$,
> Merwin wrote:
>> 2) Comment puis-je placer mon application en "fond", c'est
>> à dire qu'elle rende la main une fois qu'elle a été
>> démarée. Idem, je cherche une solution portable !



> Sous Unix, pour un serveur, le mot que tu cherches est
> "daemon", et il y a quelques trucs a faire pour creer un
> daemon: fermer tous les fd initiaux du programme et les
> rouvrir sur /dev/null, faire un cd a un endroit raisonnable
> (histoire d'eviter les problemes de montage demontage NFS),
> forker, et devenir chef de session (setsid) pour ne plus
> etre affecte par ce qui arrive au pere (qu'on laisse
> sortir).



Merci, donc en fait je dois fork() et exit() le père, en effet
je n'y avais pas pensé ! Merci ;-)



Pour commencer. Il faut bien aussi se retrouver dans un groupe
de processus à soi (pour ne pas prendre des signaux destinés à
un parent, par exemple), et normalement s'assurer aussi d'être
orphlin (pour ne pas devenir zombie). Et d'être déconnecté du
terminal.

Sous Windows, c'est complètement différent ; je crois qu'il
faut être inscrit comme « service », mais je ne connais pas
les détails.

--
James Kanze (GABI Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Avatar
espie
In article ,
James Kanze wrote:
Je crois que Boost.Asio s'adresse à un autre problème, des
entrées/sorties non bloquantes. Si tu as des threads, il n'y a
pas vraiment de motif à utiliser des entrées/sorties non
bloquantes.



Euh, si, quand meme. Si tu as des interactions entre les diverses
entrees-sorties, ca peut etre utile.

Tu veux que je te donne un cas concret qui serait merdique avec des threads?
j'ai un make parallele, qui recupere la sortie de plusieurs jobs en parallele.
Le boulot du make, c'est d'afficher les choses de facon raisonnable,
c'est-a-dire le plus possible de redecouper les entrees distinctes en ligne
(mais en restant raisonnablement temps reel, donc si tu as une ligne
incomplete, tu l'affiches et basta).

C'est assez simple a faire avec select ET des entrees non bloquantes: je
trouve un job qui a des trucs a dire, et je l'"epuise" a coups de read jusqu'a
ce qu'il n'en veuille plus, et j'ai un tampon derriere pour gerer les lignes,
et garder pour la suite. Puis je passe au suivant (je suis conscient que
mon algo n'est pas equitable, mais dans ce cas de figure, ca n'est pas un
probleme).

Ca serait relativement complexe a faire avec des threads et des mutex: de
facon naive, apres chaque lecture, mon thread prendrait la main pour
afficher des lignes completes, puis la rendrait en attendant la lecture
(bloquante) suivante. Pas du tout le meme resultat, puisque ca aurait tendance
a beaucoup plus entremeler les lignes a niveau de reactivite egale...
Avatar
espie
In article ,
James Kanze wrote:
Pour commencer. Il faut bien aussi se retrouver dans un groupe
de processus à soi (pour ne pas prendre des signaux destinés à
un parent, par exemple), et normalement s'assurer aussi d'être
orphlin (pour ne pas devenir zombie). Et d'être déconnecté du
terminal.



C'est ce que fait le setsid() plus la fermeture des fd 0, 1, 2...
Avatar
Michael DOUBEZ
James Kanze wrote:
On Mar 12, 7:41 pm, Fabien LE LEZ wrote:
On Thu, 12 Mar 2009 19:18:04 +0100,
(Pascal J. Bourguignon):



Si ton programme a des threads, tu peux ne pas avoir une
boucle d'évènement, mais juste une boucle infinie.





Utiliser des threads ici ne me paraît pas forcément la
meilleure idée. Mais même s'il utilise plusieurs threads, il
y en aura bien un qui a une boucle avec un "select" (ou
équivalent).



Pas vraiment. Je ne sais pas comment ça marche sous Windows,
mais au moins sous Unix, une fois la connexion établie, tu peux
lire et écrire le socket exactement comme un fichier. Tu crées
donc un thread par connexion (pour que l'attente sur une
connection ne bloque pas toute l'application), et ensuite, le
thread gère le socket exactement comme il ferait un fichier (ou
plutôt un tty -- les socket ne supportent pas des seek, par
exemple).



Il est généralement possible de wrapper ces mécanisme dans des classes
de façon à avoir les même interfaces osu Linux et Windows. Mais ça a été
fait des millions de fois, je ne vois pas l'intérêt de travailler avec
des notion bas niveau lorsque des bibliothèques sont disponibles.

Le select, c'est utile quand tu n'as pas de threads, et que tu
veux attendre sur plusiers sockets (ou d'autres « file
descriptor », e.g. le clavier, ou un pseudo-terminal qui
représente une fenêtre sur l'écran).

Par ailleurs, Boost.Asio m'a l'air d'inclure la gestion d'une
telle boucle.



Je crois que Boost.Asio s'adresse à un autre problème, des
entrées/sorties non bloquantes. Si tu as des threads, il n'y a
pas vraiment de motif à utiliser des entrées/sorties non
bloquantes.



Je ne connais pas bien Boost.Asio mais il implémente le pattern Reactor
qui évite beaucoup de gestion des thread et autre pour des fonctions
simple. Il peut être considéré comme une surcouche efficace de
select()/poll().

Seule la partir implémentant le pattern Proactor réalise les E/S
asynchrones et il n'est pas nécessaire de l'utiliser. (Le Reactor peut
lancer des threads pour gérer les sockets acceptées).

--
Michael
Avatar
Ael Rowen Terence
"Michael DOUBEZ" a écrit dans le message de groupe
de discussion : 49ba2b12$0$24822$
James Kanze wrote:

Il est généralement possible de wrapper ces mécanisme dans des classes de
façon à avoir les même interfaces osu Linux et Windows. Mais ça a été fait
des millions de fois, je ne vois pas l'intérêt de travailler avec des
notion bas niveau lorsque des bibliothèques sont disponibles.




Pour une meilleur compréhension.
Avatar
Michael DOUBEZ
Ael Rowen Terence wrote:


"Michael DOUBEZ" a écrit dans le message de
groupe de discussion : 49ba2b12$0$24822$
James Kanze wrote:

Il est généralement possible de wrapper ces mécanisme dans des classes
de façon à avoir les même interfaces osu Linux et Windows. Mais ça a
été fait des millions de fois, je ne vois pas l'intérêt de travailler
avec des notion bas niveau lorsque des bibliothèques sont disponibles.




Pour une meilleur compréhension.



Une meilleure compréhension de quoi ?
Des mécanismes et détails d'implémentation spécifiques à un OS ?

--
Michael
Avatar
Ael Rowen Terence
"Michael DOUBEZ" a écrit dans le message de groupe
de discussion : 49ba4fbb$0$3561$
Ael Rowen Terence wrote:


"Michael DOUBEZ" a écrit dans le message de
groupe de discussion : 49ba2b12$0$24822$
James Kanze wrote:

Il est généralement possible de wrapper ces mécanisme dans des classes
de façon à avoir les même interfaces osu Linux et Windows. Mais ça a été
fait des millions de fois, je ne vois pas l'intérêt de travailler avec
des notion bas niveau lorsque des bibliothèques sont disponibles.




Pour une meilleur compréhension.



Une meilleure compréhension de quoi ?
Des mécanismes et détails d'implémentation spécifiques à un OS ?



Oui, entre autres.
Qu'il y en est (je me compte parmi eux) pour qui réinventer la roue est une
occasion de s'améliorer, n'a rien d'abscons.
Après, que la grande-grande-majorité pense que cela ne leur servirait à
rien, c'est leur droit.
Chacun fait suivant sa sensibilité, et c'est bien ainsi.
Pourquoi ce diktat : ne pas réécrire ... alors que ce qui nous entoure est
renouvellement, même la roue des origines a été maintes fois réinventée.
Avatar
Fabien LE LEZ
On Fri, 13 Mar 2009 17:47:08 +0100, "Ael Rowen Terence"
:

Qu'il y en est (je me compte parmi eux) pour qui réinventer la roue est une
occasion de s'améliorer, n'a rien d'abscons.



Yep, mais dans ce cas, tu implémentes ta propre version d'une
bibliothèque (pour apprendre), puis tu la jettes et tu prends une
version bien testée.
1 2 3 4 5