begin process at 2013 06 20 04:22:00
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Réseaux & Internet

 > SIMPLE SERVEUR ECHO (TCP) MULTITHREAD MULTIPLATFORME (WINDOWS / *NIX)

SIMPLE SERVEUR ECHO (TCP) MULTITHREAD MULTIPLATFORME (WINDOWS / *NIX)


 Information sur la source

Note :
5,5 / 10 - par 2 personnes
5,50 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10
Catégorie :Réseaux & Internet Classé sous :serveur, tcp, thread, echo Niveau :Débutant Date de création :02/03/2007 Date de mise à jour :02/03/2007 21:24:50 Vu / téléchargé :10 439 / 992

Auteur : Cphil51

Ecrire un message privé
Commentaire sur cette source (29)
Ajouter un commentaire et/ou une note

 Description

Cliquez pour voir la capture en taille normale
Il y a déjà plein d'exemple de serveurs sur ce site. Mais je n'en ai pas trouvé qui soit simples a comprendre, petits, multi clients et portables.

Ce serveur basique est un serveur "echo" il renvoi ce que ses clients lui envoie. Il est écrit en C et est peut-être fonctionnel sous les OS Unix-like. Si quelqu'un pouvait tester la compilation sous nux ce serait sympa, je n'ai pas de distribution d'installé en ce moment (au pire il manque des entêtes à inclure).
Les threads sont gérés soit par l'API windows, soit par les pthreads.


 Conclusion

Merci de poster vos impressions. Soyez critiques.

 Fichier Zip

Les Membres Club peuvent télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip


 Historique

02 mars 2007 12:35:25 :
Ajout : allocation mémoire sécurisé.
02 mars 2007 13:07:25 :
Correction : Libération des threads sous windows.
02 mars 2007 13:57:27 :
Correction encore sur les threads...
02 mars 2007 21:15:18 :
Réorganisation légère du code. Correction sur les thread encore => tout en pthread maintenant. Le serveur ne crash plus quand un client quite comme un malpropre. Merci a max12 pour ses conseils et son aide ^^
02 mars 2007 21:24:50 :
.

 Sources de la même categorie

Source avec Zip LINUX: UTILISATION ETHTOOL (TEST DU LIEN ETHERNET, VITESSE, ... par Twinuts
Source avec Zip Source avec une capture [QT] ENVOI AUTO DE MAIL HEBDOMADAIRE par rob57530
Source avec Zip GESTIONNAIRE_FTP(CLIENT+SERVEUR) par cyberntique
Source avec Zip Source avec une capture MINI SERVEUR HTTP [WINDOWS] par ganjarasta
Source avec Zip Source avec une capture CLIENT DE TEST MODBUS TCP par brunovan

 Sources en rapport avec celle ci

Source avec Zip CHAT EN MODE CONSOLE AVEC API WINDOWS par Pylouq
Source avec Zip MINICHAT MULTI-CLIENT par wisar
Source avec Zip SERVEUR HTTP/HTTPS MULTITHREADS LINUX par naingenieur
Source avec Zip Source avec une capture [C/WIN32] PROXY AVEC THREAD par psyphi
Source avec Zip MK_SOCKET : UNE BIBLIOTHÈQUE COMPLÈTE ET TRÈS SIMPLE DE GEST... par dnob700

Commentaires et avis

Commentaire de BruNews le 02/03/2007 12:54:14 administrateur CS

Te manque une série de #ifdef, CreateThread retourne un handle qu'il convient de fermer par CloseHandle() sinon ta table de handles risque fort de saturer.

Commentaire de Cphil51 le 02/03/2007 12:59:55

Je regarde a ca tout de suite.

Commentaire de Cphil51 le 02/03/2007 13:08:35

Voila. J'ai rajouté un CloseHandle() à la fin du thread.

Commentaire de Cphil51 le 02/03/2007 14:05:19

J'ai cru comprendre sur msdn qu'un CloseHandle() ne terminait pas le thread tout de suite mais le laissait juste "tranquille". J'en conclu donc que c'est à peu prêt équivalent a pthread_detach(). J'ai donc simplifié un peu le code en faisant comme avec les pthreads.

Commentaire de ncoder le 02/03/2007 15:37:20

Bonjour,

CloseHandle() laisse le thread "tranquille" ??

Pour forcer un thread à se terminer, dois-je donc obligatoirement utiliser TerminateThread() (et non CloseHandle() ) ?

Je crois avoir lu un jour de n'utiliser que rarement TerminateThread() (en cas d'urgence), c'est vrai ?

Quelle est la différence entre TerminateThread() et CloseHandle() ?

Merci de vos réponses

Commentaire de ncoder le 02/03/2007 15:55:05

Deuxième chose :
Pourquoi tu enchaines "CloseHandle()" immédiatement après avoir fait "CreateThread()" ?

Il faudrait attendre que les threads se soient terminés tous seuls avant de faire "CloseHandle()", non ?
Sinon ils sont arrétés immédiatement après leur lancement, non ?

Dans msdn ils utilisent WaitForMultipleObjects(MAX_THREADS, hThread, TRUE, INFINITE);, et ensuite CloseHandle().
Cf : http://msdn2.microsoft.com/en-us/library/ms682516.aspx

Là je ne comprends pas tout ...

Commentaire de Cphil51 le 02/03/2007 16:54:11

Pour le CloseHandle() sur les thread, on peut lire dans msdn :

"Closing a thread handle does not terminate the associated thread. To remove a thread object, you must terminate the thread, then close all handles to the thread."
(http://msdn2.microsoft.com/en-us/library/ms724211.aspx)

Comme le thread se termine tout seul (quand le client quite...), il n'y a pas besoin de le terminer... si?

Quand a TerminateThread(), msdn nous dit que c'est une fonction dangereuse (cf. http://msdn2.microsoft.com/en-us/library/ms686717.aspx). Je pense qu'elle devrait être utilisée uniquement pour le debug d'ailleurs car trop louche à utiliser :D.

Et le WaitForMultipleObjects() sert à attendre que tous les threads soient terminés.

Je devrais théoriquement libérer l'handle du thread après l'avoir terminé, mais comme ces threads se terminent tout seuls après la fermeture des clients ça devrait être bon, non? En tout cas les essais montres que ça fonctionne :p. Essai donc le serveur avec plusieurs client telnet sur le port 1234.

Commentaire de ncoder le 02/03/2007 17:06:27

Merci pour tes réponses.

Quand le thread se termine tout seul, je pense qu'il faut quand meme faire CloseHandle().

En effet, TerminateThread() m'a l'air louche. On peut peut-etre risquer moins en faisant TerminateThread() suivi de CloseHandle()... (l'un termine le thread l'autre le ferme?)

Ce que tu me dis, c'est que comme CloseHandle() ne termine pas le thread mais juste "attend", dès que le thread se termine de lui-meme, CloseHandle() s'occupe du reste. Et ainsi tout fonctionne, et c'est pas génant que CreateThread soit immédiatement suivi de CloseHandle(), puisque celui-ci n'interrompt pas le thread durant son lancement.

Est-ce exact ?

Commentaire de Cphil51 le 02/03/2007 17:13:52

C'est WaitForMultipleObjects() qui attend que les threads soient terminés. Mais je ne l'utilise pas.
Le CloseHandle() sert juste a libérer l'handle. l'handle est indépendant du thread. C'est juste une sorte d'ID. En gros le CloseHandle() sert juste à dire a windows qu'il peut utiliser l'handle pour autre chose ; comme le thread se gère tout seul (il n'est pas contrôlé ailleurs dans le code) on en a plus besoin.

Commentaire de ncoder le 02/03/2007 17:20:16

Je connaissais l'utilité de WaitForMultipleObjects()

OK merci pour l'explication de CloseHandle().
Je mélangeais le handle et le thread, en gros.

A+ et bien pour ta source, on comprend facilement ce que tu fais.
Bonne continuation

Commentaire de Cphil51 le 02/03/2007 17:22:34

Merci ;).
Par contre j'ai remarqué un problème :/. Quand un client telnet est killé (test fais avec telnet), le serveur plante. Est ce que quelqu'un aurait une idée?

Commentaire de max12 le 02/03/2007 19:50:17 administrateur CS

Je te conseil d'utiliser uniquement PThread tant qu'a faire du multiplateforme, dans le pire des cas tu vas simplement inclure un DLL avec la version Windows, et lorsque tu voudras faire la synchronisation ce sera plus simple (et sans synchro c'est le crash).

Ensuite il y a le bug du closehandle dans ton code qui a été mensionné, il faut le faire lorsque tu en as terminé avec le thread c'est tout, dans mon cas je le faisait a la fin de la fonction du thread, mais je ne sais pas si c'est politiquement correct même si aucun problème ne survenais. Le read retourne -1 aussi parfois. Tu ne vérifie pas non plus tes memory alloc alors en cas de out of memory ton prog crash.

et finalement je suis rouillé un peu avec pthread mais il y a une commande a mettre a la fin de ta fonction client_manager quelque chose du genre p_thread_exit ou je suis pas certain (sous Nux c'était segmentation fault sinon :S)

bon c'est pas mal ce que j'avais a dire

http://www.cppfrance.com/codes/SERVEUR-MULTITHREAD-SOUS-LINUX-WINDOWS-MYSQL-VCPLUSPLUS-DEVCPLUSPLUS_40044.aspx
C'est de moi et je crois avoir été assez accomodant sur la compilation facile :P

A+

Commentaire de Cphil51 le 02/03/2007 19:52:48

Merci pour ton commentaire. J'ai donc encore ce problème de thread :p. Je me repenche sur mon code ^^.

Commentaire de Cphil51 le 02/03/2007 21:05:35

Bon j'ai trouvé la ou ça crash quand le client est killé. Sinon j'ai tout refais en pthread, j'up bientôt la nouvelle version.

Commentaire de Cphil51 le 02/03/2007 21:19:34

Voila la nouvelle version. Le serveur crashait a cause d'un -1 retourné par un recv(). J'ai aussi rajouté deux commandes clients : QUIT et VERSION.

PS : désolé pour le triple post enchainé... je ne suis pas très organisé xD.

Commentaire de amin127 le 16/04/2007 12:11:06

bonjour, je tente de le compiler sous linux et voici ce que j'ai comme erreur :
main.c:27: error: expected specifier-qualifier-list before ‘SOCKADDR_IN’
main.c: In function ‘clientManager’:
main.c:61: error: ‘socket_t’ has no member named ‘clientThread’
main.c:66: error: ‘socket_t’ has no member named ‘data’
main.c:69: warning: incompatible implicit declaration of built-in function ‘strlen’
main.c: In function ‘main’:
main.c:118: error: ‘SOCKADDR_IN’ undeclared (first use in this function)
main.c:118: error: (Each undeclared identifier is reported only once
main.c:118: error: for each function it appears in.)
main.c:131: error: ‘socket_t’ has no member named ‘data’
main.c:132: error: ‘socket_t’ has no member named ‘data’
main.c:133: error: ‘socket_t’ has no member named ‘data’
main.c:135: error: ‘SOCKADDR’ undeclared (first use in this function)
main.c:135: error: expected expression before ‘)’ token
main.c:135: error: too few arguments to function ‘bind’
main.c:142: error: expected expression before ‘)’ token
main.c:142: error: too few arguments to function ‘accept’
main.c:142: error: ‘INVALID_SOCKET’ undeclared (first use in this function)
main.c:145: error: ‘socket_t’ has no member named ‘clientThread’
main.c:145: warning: passing argument 3 of ‘pthread_create’ from incompatible pointer type

bien à toi
bonne journée

Commentaire de Cphil51 le 17/04/2007 21:58:15

Essai stp de templacer la section #else #endif du début (ou je définit les entêtes) par :

#else
#include <netdb.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define SOCKET int
#endif

Tient moi au courant, ca devrais fonctionner maintenant.

Bonne soirée

Commentaire de amin127 le 19/04/2007 12:15:15

Bonjour,
tjrs des erreurs concernant la compilation sous linux. est ce que tu peux me dire quelles sont les options de compilations que tu utilises.
Merci

Commentaire de Cphil51 le 19/04/2007 21:54:24

J'utilise Visual Studio sous windows. Je ne pense pas que ca vienne des options de compilation mais du code tel que vu sous linux. (j'ai essayé de compiler avec Code::Blocks -> ca marche et mingw est le portage de GCC).
Peux tu m'indiquer la sortie du compilateur stp (si il y a des changements même minimes surtout au niveau des SOCKADDR_IN, SOCKADDR et INVALID_SOCKET).
En fait, je ne comprend pas la première erreur:
       main.c:27: error: expected specifier-qualifier-list before ‘SOCKADDR_IN’
Celle-ci doit déclencher les 3/4 des autres.

Commentaire de amin127 le 20/04/2007 12:26:41

voilà avec : "gcc -o main main.c" c'est ce que j'obtiens:

main.c:29: error: expected specifier-qualifier-list before ‘SOCKADDR_IN’
main.c: In function ‘clientManager’:
main.c:63: error: ‘socket_t’ has no member named ‘clientThread’
main.c:68: error: ‘socket_t’ has no member named ‘data’
main.c:71: warning: incompatible implicit declaration of built-in function ‘strlen’
main.c: In function ‘main’:
main.c:120: error: ‘SOCKADDR_IN’ undeclared (first use in this function)
main.c:120: error: (Each undeclared identifier is reported only once
main.c:120: error: for each function it appears in.)
main.c:133: error: ‘socket_t’ has no member named ‘data’
main.c:134: error: ‘socket_t’ has no member named ‘data’
main.c:135: error: ‘socket_t’ has no member named ‘data’
main.c:137: error: ‘SOCKADDR’ undeclared (first use in this function)
main.c:137: error: expected expression before ‘)’ token
main.c:137: error: too few arguments to function ‘bind’
main.c:144: error: expected expression before ‘)’ token
main.c:144: error: too few arguments to function ‘accept’
main.c:144: error: ‘INVALID_SOCKET’ undeclared (first use in this function)
main.c:147: error: ‘socket_t’ has no member named ‘clientThread’
main.c:147: warning: passing argument 3 of ‘pthread_create’ from incompatible pointer type

Commentaire de Cphil51 le 20/04/2007 16:24:39

Renomme toute les références a "socket_t" et sa déclatation en "client_sock_struct" pour voire.

Commentaire de dijouxthomas le 22/04/2007 12:32:12

Bonjour,
moi aussi j'ai le même problème à la compilation sous linux et changer "socket_t" par "client_sock_struct" ne résout pas le problème.

main.c:29: error: expected specifier-qualifier-list before ‘SOCKADDR_IN’
main.c: In function ‘clientManager’:
main.c:63: error: ‘client_sock_struct’ has no member named ‘clientThread’
main.c:68: error: ‘client_sock_struct’ has no member named ‘data’
main.c: In function ‘main’:
main.c:120: error: ‘SOCKADDR_IN’ undeclared (first use in this function)
main.c:120: error: (Each undeclared identifier is reported only once
main.c:120: error: for each function it appears in.)
main.c:133: error: ‘client_sock_struct’ has no member named ‘data’
main.c:134: error: ‘client_sock_struct’ has no member named ‘data’
main.c:135: error: ‘client_sock_struct’ has no member named ‘data’
main.c:137: error: ‘SOCKADDR’ undeclared (first use in this function)
main.c:137: error: expected expression before ‘)’ token
main.c:137: error: too few arguments to function ‘bind’
main.c:144: error: expected expression before ‘)’ token
main.c:144: error: too few arguments to function ‘accept’
main.c:144: error: ‘INVALID_SOCKET’ undeclared (first use in this function)
main.c:147: error: ‘client_sock_struct’ has no member named ‘clientThread’
main.c:147: warning: passing argument 3 of ‘pthread_create’ from incompatible pointer type

Commentaire de Cphil51 le 22/04/2007 21:01:31

Hum. Et moi qui penssait que ce serait facilement portable :/.
Après un peut de recherche je pense qu'il faut que les linuxiens rajoutent ce code dans la partie #else / #endif du début du code :

/* définit dans sys/socket.h si ma mémoire est bonne : */
#define SOCKADDR_IN              socketaddr_in
#define SOCKADDR                 sockaddr

Explication :
Sous win je crois qu'il y a des macros qui les redéfinissent en majuscules.
En tout cas, j'ai regardé un document sur POSIX, et ses structures sont déclarées en
minuscules. Essais avec ces définitions la donc (a rajouter).

Toutes les autres erreurs doivent venir de ce probleme de type inconnu (le bin veut parler du clientStruct.data qui est de type inconnu par exemple), etc...

Commentaire de amin127 le 23/04/2007 15:17:52

navré mais comme tu peux le voir cela ne change rien du tout.

:>gcc -o main main.c
main.c:31: error: expected specifier-qualifier-list before ‘socketaddr_in’
main.c: In function ‘clientManager’:
main.c:65: error: ‘socket_t’ has no member named ‘clientThread’
main.c:70: error: ‘socket_t’ has no member named ‘data’
main.c:73: warning: incompatible implicit declaration of built-in function ‘strlen’
main.c: In function ‘main’:
main.c:122: error: ‘socketaddr_in’ undeclared (first use in this function)
main.c:122: error: (Each undeclared identifier is reported only once
main.c:122: error: for each function it appears in.)
main.c:135: error: ‘socket_t’ has no member named ‘data’
main.c:136: error: ‘socket_t’ has no member named ‘data’
main.c:137: error: ‘socket_t’ has no member named ‘data’
main.c:139: error: ‘sockaddr’ undeclared (first use in this function)
main.c:139: error: expected expression before ‘)’ token
main.c:139: error: too few arguments to function ‘bind’
main.c:146: error: expected expression before ‘)’ token
main.c:146: error: too few arguments to function ‘accept’
main.c:146: error: ‘INVALID_SOCKET’ undeclared (first use in this function)
main.c:149: error: ‘socket_t’ has no member named ‘clientThread’
main.c:149: warning: passing argument 3 of ‘pthread_create’ from incompatible pointer type

Au plaisir

Commentaire de Cphil51 le 23/04/2007 20:45:54

m'enerve ca... Pourtant il doit pas manquer grand chose.

Commentaire de Cphil51 le 22/12/2007 23:27:44

Bon maintenant que j'ai pu installer durablement linux sur ma machine, j'ai pu regarder a vos "problèmes". Pour ceux que ca interesse encore, il suffisais de modifier le début du code dans main.c :

...
#include <string.h>


...



#ifdef WIN32

  ...

#else

  ...
  #define SOCKADDR_IN    struct sockaddr_in
  #define SOCKADDR       struct sockaddr
  #define INVALID_SOCKET -1

  ...

#endif

C'était vraiment très compliqué... Suffisait de lire la doc...

Commentaire de Cphil51 le 22/12/2007 23:29:40

Pour info, la commande pour compiler :

gcc main.c memory.c -lpthread

Commentaire de klapaudius le 03/10/2009 00:50:29 3/10

Pas beaucoup de commentaire dans ce source pas facile pour les débutant en serveur TCP

Commentaire de fabricius le 10/11/2009 15:21:33

merci, bien pratique ton serveur pour tester une appli externe.

 Ajouter un commentaire


Discussions en rapport avec ce code source dans le forum

Serveur tcp sur plusieurs ports [ par petitchech ] Bonjours,Est il possible de faire un serveur tcp sur plusieurs ports ? recv recoit null [ par sena ] bonjour,jai un client serveur TCP tout simple en TCP.mon client envoi des caractères au serveur et le serveur lui fait un accusé de reception en lui r Serveur tcp [ par petitchech ] Bonjour,Je voudrai faire un serveur qui jere plusieurs client.Comment faire pour recuperé se qu'envoi tous les client connectés ? Client - serveur C++ avec thread [ par nono_in_maribor ] Bonjour!!Voila, je previens tout de suite je ne suis pas un pro du c++. Mon probleme est le suivant : j'ai fait un client-serveur en c++ (sous devc++) Client serveur TCP, pb multi Thread [ par valoue ] Bonjour, Voilà, je suis en train de développer un client serveur en C++ (sous VC++ .net).Pour le moment, j'ai créé le serveur et le client, ils marche Sockets asychrones et client serveur TCP [ par argali ] Bonjour,Est-ce qqun pourrait m'indiquer ou je pourrai trouver un cours complet sur les sockets asynchrones et leurs options (WSAAsyncSelect, FD_ACCEPT Serveur TCP multi-client [ par meech ] Bonjour,Je me suis attelé au développement d'un serveur TCP (extensible à divers protocoles) sous Win32 en C.Concrètement, je souhaiterais connaitre l Sections Critiques [ par new0staff ] Bonjour!Dans une partie de mon programme, j'effectue des calculs sur variables en fonction d'une trame reçu par un serveur.c'est-à-dire que lors de la Jeu réseau [ par goutbouyo ] Salut,J'essaye de mettre une fonction réseau à mon jeu.Dans l'initialisation, j'ai mis un thread qui initialise soit un serveur ou soit un client.Ensu TCP/IP [ par maitrez ] Bonjour à tous,je suis en train de créer une appli client et une appli serveur. L'appli client est un jeu qui représente pour l'instant une petite voi


Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Juin 2013
LMMJVSD
     12
3456789
10111213141516
17181920212223
24252627282930

Consulter la suite du CalendriCode

Photothèque

A découvrir



 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,655 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales