Autor |
Beitrag |
tomycat
Beiträge: 265
Erhaltene Danke: 1
|
Verfasst: Fr 08.03.19 08:53
hallo,
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:
| static void Connect(String server, String message) { try { Int32 port = 13000; TcpClient client = new TcpClient(server, port); Byte[] data = System.Text.Encoding.ASCII.GetBytes(message);
NetworkStream stream = client.GetStream();
stream.Write(data, 0, data.Length);
Console.WriteLine("Sent: {0}", message);
data = new Byte[256];
String responseData = String.Empty;
Int32 bytes = stream.Read(data, 0, data.Length); responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes); Console.WriteLine("Received: {0}", responseData);
stream.Close(); client.Close(); } catch (ArgumentNullException e) { Console.WriteLine("ArgumentNullException: {0}", e); } catch (SocketException e) { Console.WriteLine("SocketException: {0}", e); } Console.WriteLine("\n Press Enter to continue..."); Console.Read(); |
1.Frage
So funkt es 1a...
C#-Quelltext 1: 2:
| message = "BINX"; Byte[] data = System.Text.Encoding.ASCII.GetBytes(message); | Jetzt will ich es aber als Byte senden...
C#-Quelltext 1: 2:
| Byte[] data = {42,49,4e,58}; |
Idee 2:
C#-Quelltext 1: 2:
| Byte[] data = {42,49,44,58}; |
Mit Wireshark sehe ich dass *1,: übertragen wird. Wieso?
2.Frage.
Egal wie ich die Funktion sende aufrufe, es blockiert das ganze Programm. Naja, die Funktion erwartet eine Antwort. Aber wie könnte die Lösung aussehen? 2 Sekunden warten? Thread verwenden? oder als try read?
Moderiert von Th69: C#-Tags hinzugefügt
|
|
Th69
Beiträge: 4788
Erhaltene Danke: 1055
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: Fr 08.03.19 09:47
Du hast dich zwischen dezimal und hexadezimal vertan, s.a. ASCII-Tabelle.
Für hexadezimal mußt du 0x als Prefix benutzen.
Und ja, NetworkStream.Read blockiert, solange nicht genügend Daten vorliegen. Für die Umsetzung gibt es verschiedene Möglichkeiten ( Thread, Task bzw. async).
Suche am besten mal nach einem Tutorial dazu, z.B. Async Programming : Asynchronous TCP Sockets as an Alternative to WCF oder Async TCP Client .
PS: Bitte verwende die richtigen C#-Tags ( nicht {{{ ... }}}, sondern [cs]...[/cs]).
Für diesen Beitrag haben gedankt: tomycat
|
|
tomycat
Beiträge: 265
Erhaltene Danke: 1
|
Verfasst: Fr 08.03.19 13:23
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:
| private void button1_Click(object sender, EventArgs e) {
Console.WriteLine("Button1 wurde gedrückt"); Thread t = new Thread(new ThreadStart(ThreadProc)); t.Start(); Console.WriteLine("Los gehts");
}
public static void ThreadProc() { string server = "mein_ftp_server"; string message = "hello_Server"; try { Int32 port = 21; TcpClient client = new TcpClient(server, port);
Byte[] data = System.Text.Encoding.ASCII.GetBytes(message);
NetworkStream stream = client.GetStream();
stream.Write(data, 0, data.Length);
Console.WriteLine("Sent: {0}", message);
data = new Byte[256];
String responseData = String.Empty;
Int32 bytes = stream.Read(data, 0, data.Length); responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes); Console.WriteLine("Received: {0}", responseData);
stream.Close(); client.Close(); } catch (ArgumentNullException e) { Console.WriteLine("ArgumentNullException: {0}", e); } catch (SocketException e) { Console.WriteLine("SocketException: {0}", e); }
Console.WriteLine("\n Press Enter to continue..."); Console.Read(); } |
so würde es gehen, aber wie könnte der Button1 den Text hello_server dem Thread übergeben? Ich dachte wie eine Funktion, geht aber leider nicht.
|
|
Ralf Jansen
Beiträge: 4705
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Fr 08.03.19 13:48
Für die einmalige Kommunikation (Thread nach der Kommunikation beenden) kannst du den jetzigen ThreadStart Delegaten durch einen ParameterizedThreadStart Delegaten ersetzen. Der hat einen object Parameter dessen Wert du beim Aufruf von Start() mitgeben kannst.
Für alle Dinge die in deiner ThreadProc Methode IDisposable implementieren ( TcpClient, NetworkStream) solltest du über den using Syntax Dispose aufrufen. Dann wird auf wirklich immer aufgeräumt.
Moderiert von Th69: C#-Tags hinzugefügt
Für diesen Beitrag haben gedankt: tomycat
|
|
tomycat
Beiträge: 265
Erhaltene Danke: 1
|
Verfasst: Fr 08.03.19 14:20
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:
| private void button1_Click(object sender, EventArgs e) {
Console.WriteLine("Button1 wurde gedrückt");
Thread newThread = new Thread(Form1.ThreadProc); newThread.Start("42");
Console.WriteLine("Los gehts");
}
public static void ThreadProc(object datax) { string server = "mein_server"; string message = datax.ToString(); try { Int32 port = 21; TcpClient client = new TcpClient(server, port);
Byte[] data = System.Text.Encoding.ASCII.GetBytes(message);
NetworkStream stream = client.GetStream();
stream.Write(data, 0, data.Length);
Console.WriteLine("Sent: {0}", message);
data = new Byte[256];
String responseData = String.Empty;
Int32 bytes = stream.Read(data, 0, data.Length); responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes); Console.WriteLine("Received: {0}", responseData); stream.Close(); client.Close(); } catch (ArgumentNullException e) { Console.WriteLine("ArgumentNullException: {0}", e); } catch (SocketException e) { Console.WriteLine("SocketException: {0}", e); }
Console.WriteLine("\n Press Enter to continue..."); Console.Read(); } |
super Danke, letzte Frage. Ich möchte gerne responseData in die TextBox1 reinkopieren. Wie mache ich das am besten?
|
|
Ralf Jansen
Beiträge: 4705
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Fr 08.03.19 14:43
C#-Quelltext 1:
| TextBox1.Invoke((MethodInvoker)(() => { this.Text = responseData; })); |
Für diesen Beitrag haben gedankt: tomycat
|
|
tomycat
Beiträge: 265
Erhaltene Danke: 1
|
Verfasst: Fr 08.03.19 16:23
hmmmm,
ich habe deine Code Zeile unter diese...
C#-Quelltext 1:
| Console.WriteLine("Received: {0}", responseData); |
... gesetzt.
Leider macht er TextBox1 rot, sowie this.
Ich habe auch deinen Code anderen Stellen ausprobiert ohne Erfolg.
|
|
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Fr 08.03.19 17:46
- Nachträglich durch die Entwickler-Ecke gelöscht -
Für diesen Beitrag haben gedankt: tomycat
|
|
Ralf Jansen
Beiträge: 4705
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Fr 08.03.19 18:06
Zitat: | Ich möchte gerne responseData in die TextBox1 reinkopieren. |
Zitat: | Leider macht er TextBox1 rot, sowie this. |
Du hast in deinem Beitrag impliziert das es eine TextBox1 gibt. Wie heißt die den wirklich?
Möglicherweise ist auch einfach nur das Problem das du dein ThreadProc Methode statisch gemacht hast. Sobald du auf Instanzdaten zugreifen willst darf die nicht mehr statisch sein.
Für diesen Beitrag haben gedankt: tomycat
|
|
tomycat
Beiträge: 265
Erhaltene Danke: 1
|
Verfasst: Sa 09.03.19 13:45
Irgendwie habe ich den Faden verloren. Ich habe von der Toolbox eine TextBox herausgezogen und in die FORM1 gesetzt. Visual Studio hat dann daraus TextBox1 erstellt.
|
|
tomycat
Beiträge: 265
Erhaltene Danke: 1
|
Verfasst: So 10.03.19 22:09
sorry, ich steige da nicht durch.
Ich habe aus:
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| public static void ThreadProc(object datax) public void ThreadProc(object datax)
Thread newThread = new Thread(Form1.ThreadProc); Thread newThread = new Thread(ThreadProc);
TextBox1.Invoke((MethodInvoker)(() => { this.Text = responseData; })); |
Leider bleibt die TextBox1 leer.
Bin für jeden Tip Dankbar
|
|
Ralf Jansen
Beiträge: 4705
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: So 10.03.19 23:14
Ersetze this.Text durch TextBox1.Text.
Für diesen Beitrag haben gedankt: tomycat
|
|
tomycat
Beiträge: 265
Erhaltene Danke: 1
|
Verfasst: Di 12.03.19 09:57
Leider ist noch ein Problem aufgetreten...
Es ist ja so, ich sende ein Datenpacket und warte auf eine Antwort, aber passiert wenn ich keine Antwort bekomme?
Wie könnte es schaffen, dass ich mehrere Packete sende und mein Prog wartete immer ca.2 sec und eine Antwort? Sprich warte immer 2 sec., wenn keine Antwort kommt, sende das nächste Packet.
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| for(int a = 0; a < anzahl_der_Packete;a++) { send packet[a];
try { Int32 bytes = stream.Read(data, 0, data.Length); responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes); Console.WriteLine("Received: {0}", responseData); } } |
|
|
Th69
Beiträge: 4788
Erhaltene Danke: 1055
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: Di 12.03.19 10:54
Die Antwort ist immer noch dieselbe: asynchrone Programmierung, z.B. mittels Task.Delay(2000)!
Für diesen Beitrag haben gedankt: tomycat
|
|
tomycat
Beiträge: 265
Erhaltene Danke: 1
|
Verfasst: Fr 15.03.19 12:11
thx,
ich bin deinen Rat nachgegangen und habe Paraell gegooglt...
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:
| public partial class Form1 : Form { String server = "111.222.3.4"; Int32 port = 666; TcpClient client; NetworkStream stream;
public Form1() { InitializeComponent(); }
private void button1_Click(object sender, EventArgs e) { client = new TcpClient(server, port); stream = client.GetStream();
var t = Task.Run(async delegate { meinsender("test1"); await Task.Delay(1000); return 42; });
t.Wait(); t = Task.Run(async delegate { meinsender("test2"); await Task.Delay(1000); return 42; }); t.Wait();
t = Task.Run(async delegate { meinsender("test3"); await Task.Delay(1000); return 42; }); t.Wait(); stream.Close(); client.Close(); } public async Task meinsender(string nachricht) { MessageBox.Show(nachricht); Byte[] data = System.Text.Encoding.ASCII.GetBytes(nachricht); stream.Write(data, 0, data.Length); Console.WriteLine("Sent: {0}", nachricht);
data = new Byte[256]; String responseData = String.Empty; Int32 bytes = stream.Read(data, 0, data.Length); responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes); Console.WriteLine("Received: {0}", responseData); } } |
Also,
test1 ging durch und ich habe eine Antwort bekommen. Die Meldung test2 wurde angezeigt, nach Enter blockiert das Programm.
Das Programm hat nur ein Button. Ich will test1 test2 und test3 senden. Bin für jeden Tip dankbar.
|
|
jfheins
Beiträge: 918
Erhaltene Danke: 158
Win 10
VS 2013, VS2015
|
Verfasst: Fr 15.03.19 13:59
Du kannst im TclpClient die ReceiveTimeout Property setzen. Damit sollte dein Lesevorgang abgebrochen werden, wenn nichts empfangen wird.
Was du aktuell machst: Etwas empfangen (ggf. unendlich lange darauf warten) und dann noch 1 Sekunden warten. Das macht nicht so viel Sinn ...
Rein aus dem Kopf hätte ich so etwas versucht:
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| public async Task<string> reveiveWithTimeout(TcpClient client, int timeOut, int byteCount) { client.ReceiveTimeout = 5000; try { data = new Byte[byteCount]; Int32 bytes = client.GetStream().Read(data, 0, byteCount); var responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes); Console.WriteLine("Received: {0}", responseData); return responseData; } catch (IOException) { return null; } } |
Für diesen Beitrag haben gedankt: tomycat
|
|
tomycat
Beiträge: 265
Erhaltene Danke: 1
|
Verfasst: Fr 15.03.19 14:53
Ich habe die sende/empfangs Funktion so umgebaut, wenn du meinst es wäre Käse, dann erstelle ich eine Funktion für senden und eine für Empfang:
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24:
| public async Task meinsender(string nachricht) { MessageBox.Show(nachricht); Byte[] data = System.Text.Encoding.ASCII.GetBytes(nachricht); stream.Write(data, 0, data.Length); Console.WriteLine("Sent: {0}", nachricht); client.ReceiveTimeout = 2000; data = new Byte[200]; Int32 bytes = client.GetStream().Read(data, 0, 200); var responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes); Console.WriteLine("Received: {0}", responseData); } |
Zum testen habe ich mal mein ftp Server genommen.
die Ausgabe vom Visual Studio:
HTML-Dokument 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| Sent: test1 Received: 220 FTP Server ready.
Sent: test2 Ausnahme ausgelöst: "System.Net.Sockets.SocketException" in System.dll "mein-pro-idee2.vshost.exe" (CLR v4.0.30319: mein-pro-idee2.vshost.exe): "C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.resources\v4.0_4.0.0.0_de_b77a5c561934e089\System.resources.dll" geladen. Das Modul wurde ohne Symbole erstellt. Ausnahme ausgelöst: "System.IO.IOException" in System.dll Sent: test3 Ausnahme ausgelöst: "System.Net.Sockets.SocketException" in System.dll Ausnahme ausgelöst: "System.IO.IOException" in System.dll Der Thread 0x7c0 hat mit Code 0 (0x0) geendet. Der Thread 0x1b0c hat mit Code 0 (0x0) geendet. Der Thread 0x1a00 hat mit Code 0 (0x0) geendet. "mein-pro-idee2.vshost.exe" (CLR v4.0.30319: mein-pro-idee2.vshost.exe): "C:\Windows\Microsoft.Net\assembly\GAC_MSIL\mscorlib.resources\v4.0_4.0.0.0_de_b77a5c561934e089\mscorlib.resources.dll" geladen. Das Modul wurde ohne Symbole erstellt. Der Thread 0xd4c hat mit Code 0 (0x0) geendet. |
Der ftp Server muss doch nach den User fragen oder?
|
|
jfheins
Beiträge: 918
Erhaltene Danke: 158
Win 10
VS 2013, VS2015
|
Verfasst: Fr 15.03.19 17:14
Zunächst: Die SocketException zeigt dir ja an, dass es zu einem Timeout kommt.
Über die Gründe kann ich (mangels FTP Server) gerade nur spekulieren.
Wenn ich zum Beispiel das hier anschaue Müsstest du nach dem 220 vom Server direkt einen Befehl schicken, der mit "USER " anfängt
Ich glaube, wenn du einen FTP Befehl schickt, musst du auch ein Zeilenende hinterher schicken.
Für diesen Beitrag haben gedankt: tomycat
|
|
tomycat
Beiträge: 265
Erhaltene Danke: 1
|
Verfasst: So 17.03.19 12:32
Mein komplette Quelltext von mir stand der Dinge...
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:
| public partial class Form1 : Form { String server = "***.***.**.***."; Int32 port = 21; TcpClient client; NetworkStream stream; public Form1() { InitializeComponent(); }
private void button1_Click(object sender, EventArgs e) { client = new TcpClient(server, port); stream = client.GetStream(); meinempfaenger(); MessageBox.Show("moment"); var t = Task.Run(async delegate { meinsender("USER"); meinempfaenger(); await Task.Delay(1000); return 42; }); t.Wait(); t = Task.Run(async delegate { meinsender("PASS"); meinempfaenger(); await Task.Delay(1000); return 42; }); t.Wait(); t = Task.Run(async delegate { meinsender("test3"); meinempfaenger(); await Task.Delay(1000); return 42; }); t.Wait(); stream.Close(); client.Close(); } public async Task meinsender(string nachricht) { MessageBox.Show(nachricht); Byte[] data = System.Text.Encoding.ASCII.GetBytes(nachricht); stream.Write(data, 0, data.Length); Console.WriteLine("Sent: {0}", nachricht); } public async Task meinempfaenger() { Byte[] data = System.Text.Encoding.ASCII.GetBytes(""); client.ReceiveTimeout = 2000; data = new Byte[200]; Int32 bytes = client.GetStream().Read(data, 0, 200); var responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes); Console.WriteLine("Received: {0}", responseData); } } |
Die Ausgabe
HTML-Dokument 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| Received: 220 FTP Server ready.
"Idee2.vshost.exe" (CLR v4.0.30319: Idee2.vshost.exe): "C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\mscorlib.resources\v4.0_4.0.0.0_de_b77a5c561934e089\mscorlib.resources.dll" geladen. Das Modul wurde ohne Symbole erstellt. Sent: USER "Idee2.vshost.exe" (CLR v4.0.30319: Idee2.vshost.exe): "C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.resources\v4.0_4.0.0.0_de_b77a5c561934e089\System.resources.dll" geladen. Das Modul wurde ohne Symbole erstellt. Ausnahme ausgelöst: "System.IO.IOException" in System.dll Sent: PASS Ausnahme ausgelöst: "System.IO.IOException" in System.dll Sent: test3 Ausnahme ausgelöst: "System.IO.IOException" in System.dll Der Thread 0x2c90 hat mit Code 0 (0x0) geendet. Der Thread 0x2498 hat mit Code 0 (0x0) geendet. |
Vom Prinzip her möchte ich nur einen einfachen TCP CLient der sich mit einem Port verbindetet und Nachrichten versedet/empfängt.
Zum testen habe ich meinem FTP genommen. Ob ich jetzt USER oder etwas anderes sende, der FTP Server will nicht mit mir reden.
Ich hätte nie gedacht dass das so schwer ist. Egal ob ich nach der Verbindung erst sende oder etwas empfange, es will nicht.
|
|
jfheins
Beiträge: 918
Erhaltene Danke: 158
Win 10
VS 2013, VS2015
|
Verfasst: Mo 18.03.19 08:17
Versuche den Anfang mal so:
C#-Quelltext 1: 2: 3: 4: 5: 6:
| var t = Task.Run(async delegate { meinempfaenger(); meinsender("USER x \r\n"); await Task.Delay(100); }); |
Mit Zeilenumbruch
Für diesen Beitrag haben gedankt: tomycat
|
|
|