https://msdn.microsoft.com/en-us/lib...vs.110%29.aspx
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 this.Invoke(new MethodInvoker(delegate { this.TB_MessageReçu.Text += msg; }));
https://msdn.microsoft.com/en-us/lib...vs.110%29.aspx
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 this.Invoke(new MethodInvoker(delegate { this.TB_MessageReçu.Text += msg; }));
ça ne marche pas, en parlant de l'affichage du message reçu je suis toujours sur le même topic. Si je savais ce qui ne va pas je ne viendrais pas chercher de l'aide. Merci pour vos réponse. oui, merci c'est ce que j'essaye de faire par contre je n'arrive pas à voir ce que j'ai dans mes variables.
j'ai besoin d'explication, j'ai déjà du mal en c# alors passer par du VBA ça me noie.
j'ai cette fonction qui me permet d'afficher la trame reçu.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 private void messagerecu(string msg) { TB_MessageReçu.Text = TB_MessageReçu.Text + msg; }
Sauf que:
j'utilise la méthode .BeginRead qui utilise un thread secondaire
je ne peux donc pas utiliser l'appelle de cette fonction il faut que je passe par un delegate
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 byte[] inStream = new byte[clientSocket.ReceiveBufferSize]; AsyncCallback callback=new AsyncCallback(Fluxentrant); serveurStream.BeginRead(inStream, 0, inStream.Length, Fluxentrant, null);
string returndata = System.Text.Encoding.ASCII.GetString(inStream, 0, nbOctetsLus);
messagerecu(returndata);
Mais la comment faire, je trouve de tout et je n'arrive pas à me faire des convictions!
Faut il créer un delegate:
Puis créer une méthode pour ce delegate:
Code : Sélectionner tout - Visualiser dans une fenêtre à part public delegate void messagerecu(string msg);
Pour la déclaration de inStream, si je fait comme Pol m'as dit:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 private void messagerecu(string msg) { TB_MessageReçu.Text = TB_MessageReçu.Text + msg; }
j'ai cette erreur:
Code : Sélectionner tout - Visualiser dans une fenêtre à part byte[] inStream = new byte[clientSocket.ReceiveBufferSize];
Erreur 1 Un initialiseur de champ ne peut pas faire référence au champ, à la méthode ou à la propriété non statique 'Liaison_IP.Form1.clientSocket'
Voici l'intégralité du code:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Diagnostics; using System.IO; using System.Net.Sockets; using System.Net; namespace Liaison_IP { public partial class Form1 : Form { System.Net.Sockets.TcpClient clientSocket = new System.Net.Sockets.TcpClient(); byte[] inStream = new byte[clientSocket.ReceiveBufferSize]; public Form1() { InitializeComponent(); } private void BP_Connect_Click(object sender, EventArgs e) { try { clientSocket.Connect("X.X.X.X", 2101); lb_Etatduport.Text="Port ouvert"; } catch { MessageBox.Show("erreur de connexion", "erreur"); } } public void BP_Envoyer_Click(object sender, EventArgs e) { NetworkStream serveurStream = clientSocket.GetStream(); byte[] outStream = System.Text.Encoding.ASCII.GetBytes(TB_MessageEnvoye.Text+'\r'); try { serveurStream.Write(outStream, 0, outStream.Length); serveurStream.Flush(); byte[] inStream = new byte[clientSocket.ReceiveBufferSize]; AsyncCallback callback=new AsyncCallback(Fluxentrant); serveurStream.BeginRead(inStream, 0, inStream.Length, Fluxentrant, null); } catch { MessageBox.Show("erreur d'envoi", "erreur"); } } public delegate void messrec(string msg); private void messagerecu(string msg) { TB_MessageReçu.Text = TB_MessageReçu.Text + msg; } private void Initializetimertestpicto() { timertestpicto.Enabled=true; timertestpicto.Interval=60000; } public void Fluxentrant(IAsyncResult result) { int nbOctetsLus = clientSocket.GetStream().EndRead(result); if (nbOctetsLus != 0) { string returndata = System.Text.Encoding.ASCII.GetString(inStream, 0, nbOctetsLus); messrec Rec=messagerecu; clientSocket.GetStream().BeginRead(inStream, 0, inStream.Length, Fluxentrant, null); } } } }
et pourtant là pour le même problème je comprends que c'est le delegate qui te pose soucis
moi c'est du vb.net que j'ai mis, rien à voir avec vba, c'est un langage de la famille .net comme c#, et il existe des traducteurs pour passer de l'un à l'autre sur le web
quand je peux j'écris en c# ici, mais je ne prend pas toujours le temps
oui enfin moi j'ai fait un copier coller te ton code que j'ai déplacé, mais je n'aurais jamais écrit ca
ce que le compilateur veut te dire c'est qu'il ne veux pas ici que la déclaration dépende d'une autre variable
aussi mettre une valeur en dur corrige le problème (c'est 8192 que contient cette propriété par défaut pour info)
concernant le delegate quelqu'un d'autre t'as répondu en haut de page avec la syntaxe c#
éventuellement je peux ajouter l'explication du principe qu'il y a derrière
en .net il n'est pas autorisé de modifier un controle depuis un autre thread que celui l'ayant créé (le thread principal)
pour repérer ca chaque controle a une propriété InvokeRequired qui retourne true si actuellement on est dans un autre thread
et pour s'en sortir les controles ont une méthode invoke qui permet de dire au thread principal de prendre le relais pour faire un truc (donc pause le thread autre)
il faut donc lui donner un pointeur vers une méthode, qui peut etre anonyme
à l'époque il fallait un délégué, depuis ms a simplifié la syntaxe avec les méthodes anonymes (même si ca revient au même)
D'accord chef!
Mettre une valeur en dur c'est pas très flexible, c'est pour ça que j'aurais voulu que la taille de mon tableau soit dimensionner en fonction de ce qu'il reçoit, et ne pas mettre une valeur au hasard comme 15000. Comment le faire alors? le byte 8192? c'est quoi? la longueur maxi? c'est une propriété?
Donc en utilisant la syntaxe de Lead que je remercie ça fonctionne, pas besoin de créer une fonction? délégué ni méthode.
A aucun moment je passe dans
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 public void BP_Envoyer_Click(object sender, EventArgs e) { NetworkStream serveurStream = clientSocket.GetStream(); byte[] outStream = System.Text.Encoding.ASCII.GetBytes(TB_MessageEnvoye.Text+'\r'); try { serveurStream.Write(outStream, 0, outStream.Length); serveurStream.Flush(); byte[] inStream = new byte[clientSocket.ReceiveBufferSize]; AsyncCallback callback=new AsyncCallback(Fluxentrant); serveurStream.BeginRead(inStream, 0, inStream.Length, Fluxentrant, null); } catch { MessageBox.Show("erreur d'envoi", "erreur"); } } public delegate void messrec(string msg); private void messagerecu(string msg) { TB_MessageReçu.Text = TB_MessageReçu.Text + msg; } private void Initializetimertestpicto() { timertestpicto.Enabled=true; timertestpicto.Interval=60000; } public void Fluxentrant(IAsyncResult result) { int nbOctetsLus = clientSocket.GetStream().EndRead(result); if (nbOctetsLus != 0) { string returndata = System.Text.Encoding.ASCII.GetString(inStream, 0, nbOctetsLus); messrec Rec=messagerecu; clientSocket.GetStream().BeginRead(inStream, 0, inStream.Length, Fluxentrant, null); } } } }Fluxentrant(IAsyncResult result)
instream est un tableau d'octet
quand on défini un tableau on défini la taille maximum de ce tableau
au début tu avais mis tcpclient.receivebuffersize comme taille maxi
receivebuffersize est une propriété, qui si tu le modifies pas vaut 8192, donc mettre 8192 revient au même
mais ceci ne change rien au fontionnement, tu peux mettre ce que tu veux comme valeur et avoir le même fonctionnement
comme dit précédemment ceci est un buffer, donc un espace temporaire
beginread démarre un thread qui attend une réception
quand il recoit des octets, il vide le buffer de la carte réseau dans ton ta variable tableau d'octet
si ta variable est plus grande, le tableau contient des 0 après la taille de ce que as recu, d'où l'utilité de connaitre le nombre d'octets lus pour pouvoir ne prendre que ca dans sont traitement
si ta variable est plus grande, ton tableau est rempli, un si tu refais un beginread, le callback est appelé tout de suite avec la suite
donc avec un buffer 1 octet ca reviendrait au même si tu concatènes tout ce que tu recois
mais tout ca je l'ai déjà dit, il ne faut pas hésiter à relire plusieurs fois un truc pour le saisir, ca m'éviterait de l'écrire plusieurs fois
Parfait!! Merci beaucoup
Comment gérer une communication avec plusieurs équipements? Je voudrais interroger un par un les équipements.
Il faut donc que je fasse une Socket par équipement? Autant de Socket que d'équipement? J'ouvre la première Socket, j'envoi ma commande, quand je n'ai plus d'octets à lire, je traite et je ferme ma Socket et je passe à une autre Socket? assez fastidieux...
J'ai une erreur en ce moment:
Je me connecte, j'envoi une commande, je me déconnecte et quand je ferme ma fenêtre ce message d'erreur apparaît!Une exception non gérée du type 'System.ObjectDisposedException' s'est produite dans System.dll
Informations supplémentaires*: Impossible d'accéder à un objet supprimé.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Diagnostics; using System.IO; using System.Net.Sockets; using System.Net; namespace Liaison_IP { public partial class Form1 : Form { System.Net.Sockets.TcpClient clientSocket = new System.Net.Sockets.TcpClient(); byte[] inStream = new byte[15000]; public Form1() { InitializeComponent(); } private void BP_Connect_Click(object sender, EventArgs e) { try { clientSocket.Connect("X.X.X.X", 2101); lb_Etatduport.Text="Port ouvert"; } catch { MessageBox.Show("erreur de connexion", "erreur"); } } public void BP_Envoyer_Click(object sender, EventArgs e) { NetworkStream serveurStream = clientSocket.GetStream(); byte[] outStream = System.Text.Encoding.ASCII.GetBytes(TB_MessageEnvoye.Text+'\r'); try { serveurStream.Write(outStream, 0, outStream.Length); serveurStream.Flush(); AsyncCallback callback=new AsyncCallback(Fluxentrant); serveurStream.BeginRead(inStream, 0, inStream.Length, Fluxentrant, null); } catch { MessageBox.Show("erreur d'envoi", "erreur"); } } private void messagerecu(string msg) { TB_MessageReçu.Text = TB_MessageReçu.Text + msg; } private void Initializetimertestpicto() { timertestpicto.Enabled=true; timertestpicto.Interval=60000; } private void Fluxentrant(IAsyncResult result) { int nbOctetsLus = clientSocket.GetStream().EndRead(result); if (nbOctetsLus != 0) { string returndata = System.Text.Encoding.ASCII.GetString(inStream, 0, nbOctetsLus); clientSocket.GetStream().BeginRead(inStream, 0, inStream.Length, Fluxentrant, null); this.Invoke(new MethodInvoker(delegate { this.TB_MessageReçu.Text = TB_MessageReçu.Text+returndata; })); } } private void BP_Deconnecter_Click(object sender, EventArgs e) { try { if (clientSocket.Connected) clientSocket.Close(); lb_Etatduport.Text="Port Fermé"; } catch { MessageBox.Show("erreur de deconnexion", "erreur"); } } } }
il y a des chances qu'une fois le socket fermé il faille en réinstancier un autre (new)
par contre il n'est pas utile de le fermer si tu dois encore l'utiliser
et il n'y a rien de fastidieux si tu codes ca bien
comme je disais si tu fais un classe dans laquelle tu déplaces le code ca ne te fais très peu de code à ajouter
Peux tu m'aiguiller un peu plus s'il te plaît
Merci pour tout!
si tu sais faire une classe ca devrait aller
dans le constructeur de cette classe tu demandes en paramètres l'ip, le port
tu ranges ca dans des variables locales
ton tcp client en variable locale, que tu connectes dans le constructeur (begin read pareil)
une propriété public qui contient ce que tu recois
et dans ton form
tu instancies cette classes autant de fois que nécessaire
et dans un 1er temps sur un timer tu ranges le contenu de chaque instance.propriétéMessageRecu dans un textbox pour voir si ca marche
après tu adaptes à tes besoins
Bonjour,
J'ai vraiment du mal, voici ma classeIP:
Dans le form:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 namespace Liaison_IP { class ClasseIP { NetworkStream serveurStream = client.GetStream(); static void Connect(string server, string message) { Int32 port; TcpClient client = new TcpClient(server, port); } public void Messagerecu() { //NetworkStream serveurStream = clientSocket.GetStream(); byte[] inStream = new byte[15000]; client.GetStream().BeginRead(inStream, 0, inStream.Length, Fluxentrant, null); } } }
Sachant que je n'arrive pas à fermer ma socket comme dit dans un message précédent.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 namespace Liaison_IP { public partial class Form1 : Form { System.Net.Sockets.TcpClient clientSocket = new System.Net.Sockets.TcpClient(); byte[] inStream = new byte[15000]; public Form1() { InitializeComponent(); } private void TESTCOM() { try { NetworkStream serveurStream = clientSocket.GetStream(); byte[] outStream = System.Text.Encoding.ASCII.GetBytes("\r"); serveurStream.Write(outStream, 0, outStream.Length); serveurStream.Flush(); AsyncCallback callback = new AsyncCallback(Fluxentrant); serveurStream.BeginRead(inStream, 0, inStream.Length, Fluxentrant, null); } catch { MessageBox.Show("erreur de com","erreur"); } } private void BP_Connect_Click(object sender, EventArgs e) { try { clientSocket.Connect("X.X.X.X", 2101); lb_Etatduport.Text = "Port ouvert"; TESTCOM(); } catch { MessageBox.Show("erreur de connexion", "erreur"); } } public void BP_Envoyer_Click(object sender, EventArgs e) { try { NetworkStream serveurStream = clientSocket.GetStream(); byte[] outStream = System.Text.Encoding.ASCII.GetBytes(TB_MessageEnvoye.Text+'\r'); serveurStream.Write(outStream, 0, outStream.Length); serveurStream.Flush(); AsyncCallback callback=new AsyncCallback(Fluxentrant); serveurStream.BeginRead(inStream, 0, inStream.Length, Fluxentrant, null); } catch { MessageBox.Show("erreur d'envoi", "erreur"); } } private void messagerecu(string msg) { TB_MessageReçu.Text = TB_MessageReçu.Text + msg; } private void Initializetimertestpicto() { timertestpicto.Enabled=true; timertestpicto.Interval=60000; } private void Fluxentrant(IAsyncResult result) { int nbOctetsLus = clientSocket.GetStream().EndRead(result); if (nbOctetsLus != 0) { string returndata = System.Text.Encoding.ASCII.GetString(inStream, 0, nbOctetsLus); clientSocket.GetStream().BeginRead(inStream, 0, inStream.Length, Fluxentrant, null); this.Invoke(new MethodInvoker(delegate { this.TB_MessageReçu.Text = TB_MessageReçu.Text+returndata; })); } } } }
Pour interroger plusieurs équipements quand j'ai terminer de recevoir il faut bien que je ferme ma socket et en instancier une autre, avec d'autre paramètre IP et un numero de port.
Au secours!
pas eut le temps de lire le code
mais non tu n'es pas obligé de fermer le socket pour dialoguer avec un autre équipement
tu peux ouvrir plusieurs sockets en même temps (et heureusement)
d'ailleurs tu peux même interroger tous tes équipements en même temps (pas chacun leur tour)
la finalité étant d'analyser la réponse des équipements, les commandes envoyées seront pour tester l'état technique de l'équipement, suite à cette réponse, animer les équipements sur un synoptique par code couleur avec un libellé sur l'état technique, présence d'un défaut...
D'ailleurs à partir d'un fond de carte, je ne vois pas comment faire pour permettre à l'utilisateur d'ajouter, placer et configurer l'équipement qui pourrait être de plusieurs types.
Je pensais que fermer le socket était nécessaire pour ne pas perturber le réseau. mais alors pourquoi fermer le socket?
Je bloque pour cette classe, peux tu me faire un petit exemple s'il te plaît. A partir de cette classe l'instancier dans le form.. j'ai du mal
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager