Précédent   Forum des professionnels en informatique > Systèmes > Autres systèmes > Réseaux
Réseaux Réseaux, wifi, routeurs,...
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 11/05/2007, 15h26   #1
Invité de passage
 
Inscription : avril 2007
Messages : 24
Détails du profil
Informations forums :
Inscription : avril 2007
Messages : 24
Points : 4
Points : 4
Par défaut Communication telnet

Bonjour,

Depuis 2 semaines je m'interresse à la réalisation d'une Application serveur TCP en C, compilé sous Tornado et deployé sur une cible fonctionnant sous VxWorks !

Celui-ci est presque Terminée !

Aujourd'hui un nouveau problème intervient !!

J'aimerais réaliser l'application cliente qui devra tourner sur mon PC (OS : windows XP)

La solution que j'avais pensé, était simplement une communication entre ma console Telnet (qui jouerait le rôle du client), et mon Serveur (préalablement déployé sur ma cible)

Est ce Possible ? Si oui comment ?

Sinon quels autres solutions me conseilleriez vous ?

Cordialement Sebounty
sebounty est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/05/2007, 23h22   #2
Rédacteur
 
Avatar de Emmanuel Delahaye
 
Inscription : décembre 2003
Messages : 14 502
Détails du profil
Informations personnelles :
Âge : 55
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : décembre 2003
Messages : 14 502
Points : 18 103
Points : 18 103
Citation:
Envoyé par sebounty
Bonjour,

Depuis 2 semaines je m'interresse à la réalisation d'une Application serveur TCP en C, compilé sous Tornado et deployé sur une cible fonctionnant sous VxWorks !

Celui-ci est presque Terminée !

Aujourd'hui un nouveau problème intervient !!

J'aimerais réaliser l'application cliente qui devra tourner sur mon PC (OS : windows XP)

La solution que j'avais pensé, était simplement une communication entre ma console Telnet (qui jouerait le rôle du client), et mon Serveur (préalablement déployé sur ma cible)

Est ce Possible ? Si oui comment ?
Ben oui, mais quel rapport avec le langage C ?

demarrer > exécuter > telnet IP:PORT
__________________
Pas de Wi-Fi à la maison : CPL

Des infos sur la programmation et le langage C:
http://bien-programmer.blogspot.com/
http://www.bien-programmer.fr/
http://bien-programmer.forum-actif.net/forum.htm
Emmanuel Delahaye est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/05/2007, 09h46   #3
Invité de passage
 
Inscription : avril 2007
Messages : 24
Détails du profil
Informations forums :
Inscription : avril 2007
Messages : 24
Points : 4
Points : 4
Bonjour,

Ok pour lancer Telnet !

Cependant, mon probleme n'est pas resolu ! Car Ne faut t'il pas definir des parametres au préalable dans le code du serveur ?

Rappel : Mon serveur fonctionne sur une cible VxWorks!

je pense que ma console Telnet pourra jouer le rôle du client!
Mais je ne sais pas du tout comment faire !

Je suppose qu'il faudra definir un port speciale sur mon serveur : 23 ! (si ce n'est pas celui la, faites le moi savoir)
et Je suppose qu'il faudra rajouter une ou plusieurs fonctions dans mon code serveur !

Et c'est justement ces ou cette fonction que je ne sais pas parametrer et que je ne connais pas !

Citation:

La solution que j'avais pensé, était simplement une communication entre ma console Telnet (qui jouerait le rôle du client), et mon Serveur (préalablement déployé sur ma cible)

Est ce Possible ? Si oui comment ?

D'ou le fait que j'avais placé ce topic dans la rubrique C !



Cordialement (en attente d'une reponse )
sebounty est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/05/2007, 11h28   #4
Rédacteur
 
Avatar de Emmanuel Delahaye
 
Inscription : décembre 2003
Messages : 14 502
Détails du profil
Informations personnelles :
Âge : 55
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : décembre 2003
Messages : 14 502
Points : 18 103
Points : 18 103
Citation:
Envoyé par sebounty
Ok pour lancer Telnet !

Cependant, mon probleme n'est pas resolu ! Car Ne faut t'il pas definir des parametres au préalable dans le code du serveur ?
Il doit écouter sur tous les IP (INADDR_ANY) et sur un numéro de port bien précis (configuration par bind()). Certes, par défaut, telnet, c'est 23, mais le client telnet peut se connecter à n'importe quel port, il suffit de lui dire.

Citation:
Rappel : Mon serveur fonctionne sur une cible VxWorks!
Peu importe, du moment qu'il a une IP unique dans le réseau.

Cet article contient un exemple de mini-serveur fonctionnant avec Telnet :

http://emmanuel-delahaye.developpez.com/reseaux.htm

Pose des questions si tu ne comprends pas.
__________________
Pas de Wi-Fi à la maison : CPL

Des infos sur la programmation et le langage C:
http://bien-programmer.blogspot.com/
http://www.bien-programmer.fr/
http://bien-programmer.forum-actif.net/forum.htm
Emmanuel Delahaye est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/05/2007, 16h51   #5
Invité de passage
 
Inscription : avril 2007
Messages : 24
Détails du profil
Informations forums :
Inscription : avril 2007
Messages : 24
Points : 4
Points : 4
Bonjour,

Merci pour vos explications.

Mon application fonctionne en Partie.

Car lorsque je lance mon telnet de cette facon :

Citation:
demarrer > exécuter > telnet ip:port
La fenetre s'ouvre et se ferme directement.

Pour reussir mes test il m'a fallu lancer mon application de la sorte:

demarrer > exécuter > telnet > Open ip:port

Là intervient un nouveau problème: La console n'est pas instinctive.
Car après avoir fait mon Open, J'obtiens le print et les problemes suivant :

Microsoft Telnet> Open "ip:port"
Connecting to "ip:port" ....

Ensuite le curseur se place en haut de ma fenetre et je suis obligé d'ecrire sur les textes existant.
Pour valider je suis obliger de fermer la fenetre.

---------------------------------------------

Comment faire donc, pour que mon curseur se place à la suite, sur ma console Telnet Cliente ?
Comment faire pour valider le message a envoyer en appuyant sur entrée (sans avoir a fermer ma fenêtre) ?
Comment faire pour pouvoir echanger des informations entre mon Telnet et mon serveur ?
Vers quelles fonctions existante dois je alors me tourner ?

Voici mon code : Server.c (Application VxWorks)

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/* Server_V1.c - TCP server */

/* includes */ 
#include "vxWorks.h" 
#include "sockLib.h"
#include "inetLib.h" 
#include "taskLib.h" 
#include "stdioLib.h" 
#include "strLib.h" 
#include "ioLib.h" 
#include "fioLib.h" 

/* defines */
#define SERVER_PORT_NUM         23     /* server's port number for bind() */ 
#define SERVER_WORK_PRIORITY    100    /* priority of server's work task */ 
#define SERVER_STACK_SIZE       10000  /* stack size of server's work task */ 
#define SERVER_MAX_CONNECTIONS  4      /* max clients connected at a time */ 
#define REQUEST_MSG_SIZE        1024   /* max size of request message */ 
 

/* structure for requests from clients to server */ 
struct request     {     
int msgLen;                        /* length of message text */     
char message[REQUEST_MSG_SIZE];    /* message buffer */      
};

/* function declarations */
VOID tcpServerWorkTask (int sFd, char * address, u_short port);

/**************************************************************************** 
* 
* tcpServer - accept and process requests over a TCP socket 
* 
* This routine creates a TCP socket, and accepts connections over the socket 
* from clients.  Each client connection is handled by spawning a separate 
* task to handle client requests. 
* 
* This routine may be invoked as follows: 
*       -> sp tcpServer 
*       task spawned: id = 0x3a6f1c, name = t1 
*       value = 3829532 = 0x3a6f1c 
*       -> MESSAGE FROM CLIENT (Internet Address xx.xx.xx.xx, port xx): 
*       Hello out there 
* 
*/

STATUS tcpServer (void)     
	{     
	struct sockaddr_in  serverAddr;    /* server's socket address */     
	struct sockaddr_in  clientAddr;    /* client's socket address */     
	int                 sockAddrSize;  /* size of socket address structure */     
	int                 sFd;           /* socket file descriptor */     
	int                 newFd;         /* socket descriptor from accept */     
	int                 ix = 0;        /* counter for work task names */     
	char                workName[16];  /* name of work task */

        /* set up the local address */
        sockAddrSize = sizeof (struct sockaddr_in);     
	bzero ((char *) &serverAddr, sockAddrSize);     
	serverAddr.sin_family = AF_INET;     
	serverAddr.sin_len = (u_char) sockAddrSize;     
	serverAddr.sin_port = htons (SERVER_PORT_NUM);     
	serverAddr.sin_addr.s_addr = htonl (INADDR_ANY);

        /* create a TCP-based socket */
    	if ((sFd = socket (AF_INET, SOCK_STREAM, 0)) == ERROR)         
		{         
		perror ("socket");         
		return (ERROR);         
		}

		printf ("xxxxxx**********TCP-based Socket Ok**********xxxxxx\n");

        /* bind socket to local address */
    	if (bind (sFd, (struct sockaddr *) &serverAddr, sockAddrSize) == ERROR)         
		{         
		perror ("bind");         
		close (sFd);         
		return (ERROR);         
		}

		printf ("xxxxxx**********Bind Socket Ok**********xxxxxx\n");

	/* create queue for client connection requests */
    	if (listen (sFd, SERVER_MAX_CONNECTIONS) == ERROR)         
		{         
		perror ("listen");         
		close (sFd);         
		return (ERROR);         
		}
		printf ("xxxxxx**********Listening on Port %d Ok**********xxxxxx\n", SERVER_PORT_NUM);

	/* accept new connect requests and spawn tasks to process them */
        FOREVER         
		{         
		if ((newFd = accept (sFd, (struct sockaddr *) &clientAddr,&sockAddrSize)) == ERROR)             
			{             
			perror ("accept");             
			close (sFd);             
			return (ERROR);             
			}
        	sprintf (workName, "tTcpWork%d", ix++);
	        if (taskSpawn(workName, SERVER_WORK_PRIORITY, 0, SERVER_STACK_SIZE,
		       (FUNCPTR) tcpServerWorkTask, newFd,(int) inet_ntoa (clientAddr.sin_addr),
		       ntohs (clientAddr.sin_port),0, 0, 0, 0, 0, 0, 0) == ERROR)             
			{             
			/* if taskSpawn fails, close fd and return to top of loop */              

			perror ("taskSpawn");             
			close (newFd);             
			}         
		}     
	}  

/**************************************************************************** 
* 
* tcpServerWorkTask - process client request message 
* 
* This routine reads from the server's socket, and processes client 
* request message.
* 
* RETURNS: N/A. 
*/  

VOID tcpServerWorkTask     
	(     
	int             sFd,            /* server's socket fd */     
	char *          address,        /* client's socket address */     
	u_short         port            /* client's socket port */     
	)     
	{     
	struct request      clientRequest;  /* request/message from client */     
	int                 nRead;          /* number of bytes read */     

	/* read client request, display message */      
	while ((nRead = fioRead (sFd, (char *) &clientRequest,sizeof (clientRequest))) > 0)         
		{         
		printf ("MESSAGE FROM CLIENT (Internet Address %s, port %d):\n%s\n",                  
			address, port, clientRequest.message);         
		}      
		if (nRead == ERROR)                 /* error from read() */         
		perror ("read");      
		close (sFd);                        /* close server socket connection */     
	}
Merci

PS: Votre Site est très bien fait il m'a été d'une aide precieuse.
sebounty est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/05/2007, 19h30   #6
Rédacteur
 
Avatar de Emmanuel Delahaye
 
Inscription : décembre 2003
Messages : 14 502
Détails du profil
Informations personnelles :
Âge : 55
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : décembre 2003
Messages : 14 502
Points : 18 103
Points : 18 103
Citation:
Envoyé par sebounty
Pour reussir mes test il m'a fallu lancer mon application de la sorte:
demarrer > exécuter > telnet > Open ip:port
Bizarre, chez moi, ça fonctionne. Par exemple :

telnet 127.0.01:4000

ouvre le port 4000 d'un serveur local.
Citation:
Là intervient un nouveau problème: La console n'est pas instinctive.
Car après avoir fait mon Open, J'obtiens le print et les problemes suivant :

Microsoft Telnet> Open "ip:port"
Connecting to "ip:port" ....

Ensuite le curseur se place en haut de ma fenetre et je suis obligé d'ecrire sur les textes existant.
Pour valider je suis obliger de fermer la fenetre.

---------------------------------------------

Comment faire donc, pour que mon curseur se place à la suite, sur ma console Telnet Cliente ?
Comment faire pour valider le message a envoyer en appuyant sur entrée (sans avoir a fermer ma fenêtre) ?
Comment faire pour pouvoir echanger des informations entre mon Telnet et mon serveur ?
Vers quelles fonctions existante dois je alors me tourner ?

Voici mon code : Server.c (Application VxWorks)
Il faut terminer les lignes par CR/LF (ASCII : 13/10)

Pour le moment, le serveur n'envoit rien.

Pour faire une "saisie", il faut que les données entrantes soient interprétées.

En mode Telnet, tout ce qui est tapé sur le clavier du terminal (clent) est transmis immédiatement. Le serveur reçoit en gros une trame par caractères saisis. Ils doivent être accumulés et quand ils forment une commande complète (séquence de caractères terminée par un \r, ASCII : 10), celle-ci est interprétée.
__________________
Pas de Wi-Fi à la maison : CPL

Des infos sur la programmation et le langage C:
http://bien-programmer.blogspot.com/
http://www.bien-programmer.fr/
http://bien-programmer.forum-actif.net/forum.htm
Emmanuel Delahaye est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/05/2007, 16h59   #7
Invité de passage
 
Inscription : avril 2007
Messages : 24
Détails du profil
Informations forums :
Inscription : avril 2007
Messages : 24
Points : 4
Points : 4
Bonjour,

Je reste bloqué au niveau du retour chariot !

Ma chaine de caracteres n'est envoyé que si la console Telnet se ferme.

Dans mon Telnet j'ai validé CR/LF. en faisant : "set crlf"
lors du display (commande telnet) je vois bien : "New line mode - Causes return key to send CR & LF"

Mon erreur se trouverait elle dans mon code vu précedement?



Par la suite j'aimerais que mon client Telnet affiche des informations !

Au début un simple printf qui serait une forme d'accusé de reception! (Exemple "la chaine de caractere a bien été recu".)

Est ce Possible? Si oui comment faire Comment faire?

Encore merci

Cordialement Sebounty
sebounty est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/05/2007, 18h11   #8
Rédacteur
 
Avatar de Emmanuel Delahaye
 
Inscription : décembre 2003
Messages : 14 502
Détails du profil
Informations personnelles :
Âge : 55
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : décembre 2003
Messages : 14 502
Points : 18 103
Points : 18 103
Citation:
Envoyé par sebounty
Je reste bloqué au niveau du retour chariot !

Ma chaine de caracteres n'est envoyé que si la console Telnet se ferme.
La chaine de caractère émise par qui ? En matière d'application réseau, il faut être particulièrement précis sur les termes.
Citation:
Dans mon Telnet j'ai validé CR/LF. en faisant : "set crlf"
lors du display (commande telnet) je vois bien : "New line mode - Causes return key to send CR & LF"

Mon erreur se trouverait elle dans mon code vu précedement?
En principe, on a pas besoin de ça. Le LF 'naturel' suffit. En fait ça dépend de ce qu'attend le serveur.

Ton Telnet est bien reglé en mode terminal ? (Mode par défaut, à ma connaissance).

Citation:
Par la suite j'aimerais que mon client Telnet affiche des informations !

Au début un simple printf qui serait une forme d'accusé de reception! (Exemple "la chaine de caractere a bien été recu".)
Il n'y a rien à faire de particulier. Un client Telnet, c'est juste un terminal. Il affiche exactement ce qu'envoie le serveur. Ni plus ni moins. (aux fins de lignes près, selon la configuration).
__________________
Pas de Wi-Fi à la maison : CPL

Des infos sur la programmation et le langage C:
http://bien-programmer.blogspot.com/
http://www.bien-programmer.fr/
http://bien-programmer.forum-actif.net/forum.htm
Emmanuel Delahaye est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/05/2007, 11h41   #9
Invité de passage
 
Inscription : avril 2007
Messages : 24
Détails du profil
Informations forums :
Inscription : avril 2007
Messages : 24
Points : 4
Points : 4
Bonjour,

Citation:
La chaine de caractère émise par qui ?
Dans mon code :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
VOID tcpServerWorkTask     
	(     
	int             sFd,            /* server's socket fd */     
	char *          address,        /* client's socket address */     
	u_short         port            /* client's socket port */     
	)     
	{     
	struct request      clientRequest;  /* request/message from client */     
	int                 nRead;          /* number of bytes read */     

	/* read client request, display message */      
	while ((nRead = fioRead (sFd, (char *) &clientRequest,sizeof (clientRequest))) > 0)         
		{         
		printf ("MESSAGE FROM CLIENT (Internet Address %s, port %d):\n%s\n",                  
			address, port, clientRequest.message);         
		}      
		if (nRead == ERROR)                 /* error from read() */         
		perror ("read");      
		close (sFd);                        /* close server socket connection */     
	}
cette fonction lit la chaine de caracteres emise par le client Telnet !
Donc pour être plus precis, pour valider la chaine de caracteres emise par Telnet je suis obligé de fermer la console Telnet.

Lorsque je fais display je suis bien en mode Console et non Stream !

Citation:
Il n'y a rien à faire de particulier. Un client Telnet, c'est juste un terminal. Il affiche exactement ce qu'envoie le serveur. Ni plus ni moins. (aux fins de lignes près, selon la configuration).
Donc si je comprends bien, Il ne me sera pas possible par la suite de coder des raccourcis sous forme de case (a partir du serveur !) qui pourraient afficher sur la console Telnet un menu inteligent.

Exemple: faire en sorte que le caractere 1 (sur ma console cliente Telnet) corresponde a un envoi vers la Target (VxWorks) de la commande "version", recuperer la valeur (Ici une chaine de caracteres) et l'afficher sur mon Telnet !

Dois je obligatoirement faire une application cliente console en C pour mon host ?

Cordialement Sebounty
sebounty est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/05/2007, 12h55   #10
Rédacteur
 
Avatar de Emmanuel Delahaye
 
Inscription : décembre 2003
Messages : 14 502
Détails du profil
Informations personnelles :
Âge : 55
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : décembre 2003
Messages : 14 502
Points : 18 103
Points : 18 103
Citation:
Envoyé par sebounty
Dans mon code :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
VOID tcpServerWorkTask     
	(     
	int             sFd,            /* server's socket fd */     
	char *          address,        /* client's socket address */     
	u_short         port            /* client's socket port */     
	)     
	{     
	struct request      clientRequest;  /* request/message from client */     
	int                 nRead;          /* number of bytes read */     

	/* read client request, display message */      
	while ((nRead = fioRead (sFd, (char *) &clientRequest,sizeof (clientRequest))) > 0)         
		{         
		printf ("MESSAGE FROM CLIENT (Internet Address %s, port %d):\n%s\n",                  
			address, port, clientRequest.message);         
		}      
		if (nRead == ERROR)                 /* error from read() */         
		perror ("read");      
		close (sFd);                        /* close server socket connection */     
	}
cette fonction lit la chaine de caracteres emise par le client Telnet !
Donc pour être plus precis, pour valider la chaine de caracteres emise par Telnet je suis obligé de fermer la console Telnet.
Non, ça, c'est pas possible. Dans un terminal en mode caractères, chaque caractère frappé est émis immédiatement (ou presque) dans une trame. En gros, on reçoit une trame par caractère, ce qui oblige, à la réception, à 'assembler' les caractères reçus pour en faire une commande (terminée par \r, en général).

Dans ce genre d'application, j'utilisais ceci pour faire 'l'assemblage' :

http://emmanuel-delahaye.developpez.com/clib.htm
Module REC

Citation:
Lorsque je fais display je suis bien en mode Console et non Stream !
Il faut être en mode 'caractères' (mode par défaut des clients Telnet) et non 'blocs'.
Citation:
Donc si je comprends bien, Il ne me sera pas possible par la suite de coder des raccourcis sous forme de case (a partir du serveur !) qui pourraient afficher sur la console Telnet un menu inteligent.
Tu fait absolument ce que tu veux du moment que tu sais récupérer ce qu'envoie la console Telnet.
Citation:
Exemple: faire en sorte que le caractere 1 (sur ma console cliente Telnet) corresponde a un envoi vers la Target (VxWorks) de la commande "version", recuperer la valeur (Ici une chaine de caracteres) et l'afficher sur mon Telnet !
Aucun problème pour faire ça, mais c'est de l'applicatif. Il faut travailler en 'couches'. Mon petit module 'REC' permet de créer un 'callback' qui active la couche supérieure (interpréteur de commandes ou de menu etc.) dès qu'une commande complète et valide est reçue.
Citation:
Dois je obligatoirement faire une application cliente console en C pour mon host ?
Non. Tu peux absolument le piloter par une série d'écran visibles et pilotables par un Telnet. C'est très classique (je suggère quand même de gérer une session par un login/mot de passe, avec delog automatique en cas d'inactivité, pour éviter les intrusions non désirées...)
__________________
Pas de Wi-Fi à la maison : CPL

Des infos sur la programmation et le langage C:
http://bien-programmer.blogspot.com/
http://www.bien-programmer.fr/
http://bien-programmer.forum-actif.net/forum.htm
Emmanuel Delahaye est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/05/2007, 16h25   #11
Invité de passage
 
Inscription : avril 2007
Messages : 24
Détails du profil
Informations forums :
Inscription : avril 2007
Messages : 24
Points : 4
Points : 4
Bonjour,

m'etant absenté ces derniers jours, je n'ai pu reprendre mon projet qu'aujourd'hui.

Voici les modifications que j'ai apporté à la fonction recuperant la chaine de caracteres emise par le terminal Telnet.
J'ai defini le caractere zèro pour indiquer que ma chaine se termine, en pensant que mon bug allait être corrigé.

Precision: j'ai dit:
Citation:
Donc pour être plus precis, pour valider la chaine de caracteres emise par Telnet je suis obligé de fermer la console Telnet.
en effet lorsque je ferme mon terminal, la chaine de caracteres est envoyée.
Cela revient a dire: Lorsque je me deconnecte, avec mon client Telnet, du serveur, la chaine de caracteres est envoyée.

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
VOID tcpServerWorkTask     
	(     
	int             newFd,           /* server's socket fd */     
	char *          address,        /* client's socket address */     
	u_short         port            /* client's socket port */     
	)     
	{     
	struct request      clientRequest;  /* request/message from client */     
	int                 nRead;          /* number of bytes read */     

	/* read client request, display message */      
	while ((nRead = fioRead (newFd, (char *) &clientRequest,sizeof (clientRequest))) != ERROR)         
		{
			if(nRead > 0)
			{
				clientRequest.message[nRead]=0;         
				printf ("MESSAGE FROM CLIENT (Internet Address %s, port %d):\n%s\n",                  
				address, port, clientRequest.message);
			}         
		}      
		if (nRead == ERROR)                 /* error from read() */         
		perror ("read");      
		close (newFd);                       /* close server socket connection */     
	}
D'ou peut provenir ce problème ?

Car a chaque fois que je veux envoyer une chaine de caractères je suis obligé de me deconnecter avec mon client.

Comment faire pour que cette chaine soit envoyée par la simple pression de la touche entrée ?

Merci Sebounty
sebounty est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/05/2007, 16h37   #12
Membre émérite
 
Inscription : avril 2007
Messages : 868
Détails du profil
Informations personnelles :
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : avril 2007
Messages : 868
Points : 963
Points : 963
Envoyer un message via ICQ à Mark Havel Envoyer un message via MSN à Mark Havel
Juste une question en passant : il n'y a pas de serveur Telnet (ou ssh) fourni avec VxWorks ? Ca permettrait d'accéder à l'interface de commande de la cible plus simplement qu'en refaisant un Telnet non ?
Mark Havel est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/05/2007, 16h54   #13
Rédacteur
 
Avatar de Emmanuel Delahaye
 
Inscription : décembre 2003
Messages : 14 502
Détails du profil
Informations personnelles :
Âge : 55
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : décembre 2003
Messages : 14 502
Points : 18 103
Points : 18 103
Citation:
Envoyé par sebounty
Voici les modifications que j'ai apporté à la fonction recuperant la chaine de caracteres emise par le terminal Telnet.
J'ai defini le caractere zèro pour indiquer que ma chaine se termine, en pensant que mon bug allait être corrigé.
Non. L'usage est : pas de zéro en ligne en mode texte. C'est généralement le caractère CR ('\r') ou LF ('\n') (à définir, c'est ton protocole) qui marque la fin de ligne.

EDIT : En regardant ton code, je vois une structure. Tu fais donc du transfert de données binaire ? C'est pas clair ton histoire. A ma connaissance, Telnet, c'est uniquement pour du mode texte.

As-tu fait des études préalables ? Est-ce que tu sais exactement ce que tu as à faire ? Où sont les specs, l'analyse ?
Citation:
Precision: j'ai dit:
en effet lorsque je ferme mon terminal, la chaine de caracteres est envoyée.
Cela revient a dire: Lorsque je me deconnecte, avec mon client Telnet, du serveur, la chaine de caracteres est envoyée.
Totalement anormal. Il y a un bug quelque part... Tu parles de quel client Telnet ? Un que tu as écrit ou un client officiel comme celui de Windows ou de GNU/Linux ?
Citation:
D'ou peut provenir ce problème ?
Ce code semble être la partie réception d'un serveur. (pourquoi est-il si mal présenté ?)

analyse en cours...

Car a chaque fois que je veux envoyer une chaine de caractères je suis obligé de me deconnecter avec mon client.

Citation:
Commet faire pour que cette chaine soit envoyée par la simple pression de la touche entrée ?
Un client telnet (de base) c'est un simple terminal. Il suffit de faire ceci :

(pseudo-code)
Code :
1
2
3
4
5
6
7
8
9
   fin := FALSE
   TANT QUE NON fin
      caractere := lire-un-caractere()
      fin := caractere = ESC ; par exemple
      SI NON fin
        send (socket, caractere)
      FIN SI
   FIN TANT QUE
Si tu ne disposes pas de fonction 'lire-un-caractere' (par exemple, en C ou en Turbo Pascal, getch() de conio), il faut travailler en mode ligne :

(pseudo-code)
Code :
1
2
3
4
5
6
7
8
9
   fin := FALSE
   TANT QUE NON fin
      commande := lire-une-ligne()
      fin := commande = "quit" ; par exemple
      SI NON fin
        send (socket, ligne)
      FIN SI
   FIN TANT QUE
Fait ton choix et fait ton implémentation en C. C'est assez trivial...

Pour faire un serveur Telnet de base c'est :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
   fin := FALSE
   chaine_recu := ""
   TANT QUE NON fin
      recv (socket, donnees)
      chaine_recu = chaine_recu + donnees
      SI est_complete (chaine_recu, commande)      
         fin := commande = "quit" ; par exemple
         SI NON fin
            traiter(commande)
         FIN SI
      FIN SI
   FIN TANT QUE
il n'y a rien de compliqué, mais il fait le faire correctement.

Se rappeler qu'en TCP, la chronologie et l'intégrité des données est respectée, mais que les données reçues peuvent être 'découpées' par rapport aux données émises... Il faut donc les reconstituer avant de les traiter.
__________________
Pas de Wi-Fi à la maison : CPL

Des infos sur la programmation et le langage C:
http://bien-programmer.blogspot.com/
http://www.bien-programmer.fr/
http://bien-programmer.forum-actif.net/forum.htm
Emmanuel Delahaye est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/05/2007, 18h11   #14
Invité de passage
 
Inscription : avril 2007
Messages : 24
Détails du profil
Informations forums :
Inscription : avril 2007
Messages : 24
Points : 4
Points : 4
Alors le projet que je dois faire consiste à :

Créer un ensemble applicatif client-serveur.
Le client (sur mon Host) est un terminal Telnet Officiel (Windows).
Le serveur est le programme vu dans les posts précedents.

L'objectif est de faire communiquer ces 2 applications.

Le client devra envoyer une commande typic VxWorks (exemple "version" qui affichera la version du kernel).

Le serveur devra alors lui renvoyer le resultat, de cette commande.( dans cette exemple "VxWorks.... V1.2...")

Pour finir le client devra afficher ce resultat à l'ecran, et l'enregistrer dans un fichier.

Pour le moment j'essaye d'envoyer une chaine de caractere, mais cette fonction n'a aucun avenir dans mon programme. C'est juste histoire de me faire la main.

Citation:
Un client telnet (de base) c'est un simple terminal. Il suffit de faire ceci :

(pseudo-code)

Code :
1
2
3
4
5
6
7
8
9
Code :
   fin := FALSE
   TANT QUE NON fin
      caractere := lire-un-caractere()
      fin := caractere = ESC ; par exemple
      SI NON fin
        send (socket, caractere)
      FIN SI
   FIN TANT QUE
Si tu ne disposes pas de fonction 'lire-un-caractere' (par exemple, en C ou en Turbo Pascal, getch() de conio), il faut travailler en mode ligne :

(pseudo-code)

Code :
1
2
3
4
5
6
7
8
9
Code :
   fin := FALSE
   TANT QUE NON fin
      commande := lire-une-ligne()
      fin := commande = "quit" ; par exemple
      SI NON fin
        send (socket, ligne)
      FIN SI
   FIN TANT QUE
Fait ton choix et fait ton implémentation en C. C'est assez trivial...

Pour faire un serveur Telnet de base c'est :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
Code :
   fin := FALSE
   chaine_recu := ""
   TANT QUE NON fin
      recv (socket, donnees)
      chaine_recu = chaine_recu + donnees
      SI est_complete (chaine_recu, commande)      
         fin := commande = "quit" ; par exemple
         SI NON fin
            traiter(commande)
         FIN SI
      FIN SI
   FIN TANT QUE
il n'y a rien de compliqué, mais il fait le faire correctement.

Se rappeler qu'en TCP, la chronologie et l'intégrité des données est respectée, mais que les données reçues peuvent être 'découpées' par rapport aux données émises... Il faut donc les reconstituer avant de les traiter.
Ok mais Ou ? et comment considerer ma fin de chaine (en supposant que ce n'est pas le caractere 0) ?

Merci Sebounty
sebounty est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/05/2007, 18h44   #15
Rédacteur
 
Avatar de Emmanuel Delahaye
 
Inscription : décembre 2003
Messages : 14 502
Détails du profil
Informations personnelles :
Âge : 55
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : décembre 2003
Messages : 14 502
Points : 18 103
Points : 18 103
Citation:
Envoyé par sebounty
Alors le projet que je dois faire consiste à :

Créer un ensemble applicatif client-serveur.
Le client (sur mon Host) est un terminal Telnet Officiel (Windows).
Le serveur est le programme vu dans les posts précedents.

L'objectif est de faire communiquer ces 2 applications.

Le client devra envoyer une commande typic VxWorks (exemple "version" qui affichera la version du kernel).

Le serveur devra alors lui renvoyer le resultat, de cette commande.( dans cette exemple "VxWorks.... V1.2...")
OK. un shell classique.

Citation:
Pour finir le client devra afficher ce resultat à l'ecran,
OK, c'est le travail 'de base' d'un client Telnet
Citation:
et l'enregistrer dans un fichier.
Ca, par contre, je ne suis pas sûr que le client Telnet de Windows sache faire ça. De toutes façons, à moins d'en écrire un, tu ne peux pas y faire grand chose (ou en trouver un autre sur le net...)
Citation:
Pour le moment j'essaye d'envoyer une chaine de caractere, mais cette fonction n'a aucun avenir dans mon programme. C'est juste histoire de me faire la main.
Ah ? Et dans la vrai vie, tu comptes envoyer quoi avec ton client Telnet ? A ma connaissance, il ne sait pas faire autre chose (ou alors peut être du FTP, mais il va falloir implémenter FTP sur ton serveur...)
Citation:
Ok mais Ou ? et comment considerer ma fin de chaine (en supposant que ce n'est pas le caractere 0) ?
Ben facile. Sur le client Telnet (qui est un terminal 'caractères', on est bien d'accord), quand tu tapes une commande, tu termines par <ENTER> ce qui se traduit par un CR ou un LF ou un CR+LF selon la configuration du terminal (important pour la réception).

Par exemple :

Génère très probablement les trames de données (on suppose que <enter> -> LF)

"h"
"e"
"l"
"p"
"\n"

même si on tape vite.

Rappel : en mode caractère, dès qu'un caractère est tapé, il est émis sans attendre le <enter>. D'ailleurs, si tu veux gérer la correction (BS) et l'écho distant, il faut tout faire à la main dans le serveur... On a tout intérêt à traiter les caractères un à un dans une routine séparée de la réception.

Par exemple (kinda pseudo-C code) :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
int fin = 0;
while (!fin)
{
   char data[32]; /* taille arbitraire */
   int n = recv (socket, data, sizeof data, 0);
   if (n > 0)
   {
      int i;
      for (i = 0; i < n; i++)
      {
         char commande[128];
         int c = data[i];

         /* emet echo et BS */
         int ok = traitement_caractere (socket, c, commande); 
         if (ok)
         {
            /* execute la commande et emet la reponse */
            fin = interpreteur (socket, commande); 
         }
      }
   }
}
__________________
Pas de Wi-Fi à la maison : CPL

Des infos sur la programmation et le langage C:
http://bien-programmer.blogspot.com/
http://www.bien-programmer.fr/
http://bien-programmer.forum-actif.net/forum.htm
Emmanuel Delahaye est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 19h19.


 
 
 
 
Partenaires

Hébergement Web