Benutzer mit den meisten Antworten
TCPClient senden/empfangen spacer

Frage
-
Ich möchte einen TCPClient programmieren,
ich bin momentan soweit, das ich Bytes zum server(ein Gerät) senden kann,
jedoch muss ich noch die rückmeldung des servers angezeigt bekommen.
Sprich: ich sende bytes, jenachdem welche Byteanordnung ich sende
bekomme ich unterschiedliche meldungen zurück, jedoch weiß ich nicht
recht mit der "recv Function" umzugehen um die ergebnisse in meinem
Programm auszugeben.
Was fehlt, damit ich auch empfangen kann?using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
namespace TCPClient
{
class TCPClientClass
{
static void Main(string[] args)
{
TcpClient tcpClient = new TcpClient();
tcpClient.Connect("Localhost", 1002);
if (tcpClient.Connected)
{
NetworkStream NS = tcpClient.GetStream();
Console.WriteLine("Bytemuster wird übertragen...");
//ControlBytes als Hexdatei
byte[] array = new byte[12];
array[0] = 0x02; array[1] = 0x00; array[2] = 0x09;
array[3] = 0x03; array[4] = 0x68; array[5] = 0x01;
array[6] = 0x0E; array[7] = 0x57; array[8] = 0x00;
array[9] = 0x01; array[10] = 0x03; array[11] = 0x03;
//Hexdatein übertragen
NS.Write(array, 0, 12);
}
}
}
}
Antworten
-
Am 15.09.2011 14:34, schrieb Miele2008:> private void cmdSendenEmpfangen_Click_1(object sender, EventArgs e)> {> try> {> ns = client.GetStream();> // hier schicke/schreibe ich 12 Byte in Networkstream> ns.Write(request(), 0, 12);>> // hier möchte ich die 12 Byte, die das Gerät schickt, aus dem Networkstream lesen> //......> }Dazu brauchst du keinen TcpListener oder sowas, auch nicht deine eigeneIP Adresse, das geht ganz einfach mit Stream.Read(). Einen extra StartButton brauchst du auch nicht. Das ist sogenannte synchrone Übertragung,die funktioniert vielleicht erstmal, hat aber sonst nur Nachteile. Ambesten du vergisst, dass es sowas überhaupt gibt. Die Nachteile sind sozahlreich, dass sie diesen Artikel sprengen würden.Besser ist asynchron, nicht mit Read(...), sondern mit BeginRead(...)und einer CallBack() Funktion, so wie in meinem ersten Beispiel. DerCallback wird automatisch aufgerufen wenn Daten ankommen, das wird durchBeginRead(...) initiiert. Dabei musst du nur aufpassen, dass dabei unterder Haube ein neuer Thread erzeugt wird, in welchem du keinen Zugriffauf das UI hast. Wenn du im UI vom Callback aus was manipulieren willst,musst du über Invoke(...) gehen.Wenn du aber trotz aller Empfehlungen unbedingt bei synchron bleibenwillst, kannst du das so machen:private void cmdSendenEmpfangen_Click(object sender, EventArgs e){Byte[] recvBuf = new Byte[123];try{Byte[] array = new Byte[]{ 0x02,0x00,0x09,0x03,0x68,0x01,0x0E,0x57,0x00,0x01,0x03,0x03 };ns = Remote.GetStream();// hier schicke/schreibe ich 12 Byte in Networkstreamns.Write(array, 0, array.Length);// hier möchte ich die 12 Byte, die das Gerät schickt, aus demNetworkstream lesen//......int numRead = ns.Read(recvBuf, 0, recvBuf.Length);}Du kannst die Größe von Arrays überigens jederzeit zur Laufzeitbestimmen und auf deine magische '12' im Quelltext verzichten. Dasbringt irgendwann nur Probleme, glaub es. Für wirklich robusten Codefehlt hier allerdings noch 'ne Menge Exception handling;Hajü
- Als Antwort markiert Miele2008 Sonntag, 18. September 2011 15:37
Alle Antworten
-
Ich habe das wie folgt realisiert: Die Übertragung erfolgt asynchron,das ist auf jeden Fall vorzuziehen. Da brauchst du nicht explizit aufeine Antwort zu warten. Wann immer Daten ankommen wird derReadCallback() automatisch aufgerufen. Ein paar aus dem Zusammenhanggerissene Fragmente (ich sende Text hin und her, der wird aber in Byteskonvertiert):Byte[] recvBuf = new Byte[1024];TcpClient Remote = new TcpClient(AddressFamily.InterNetwork);private void btnConnect_Click(object sender, EventArgs e){try{Remote.Connect(tbHostname.Text, Convert.ToInt32(tbPort.Text));Remote.GetStream().BeginRead(recvBuf, 0, recvBuf.Length,ReadCallback, null);}catch (Exception ex){MessageBox.Show(ex.Message);}}private void btnSend_Click(object sender, EventArgs e){Remote.GetStream().Write(Encoding.ASCII.GetBytes(strRequest), 0,strRequest.Length);} // End btnSend_Clickprotected void ReadCallback(IAsyncResult ar){int numRead = 0;try{if (Remote.Connected == true)numRead = Remote.GetStream().EndRead(ar);}catch (IOException ex){// Da bin ich mir nicht wirklich sicher, das passiert wenn derremote Host von sich aus die Verbindung unerwartet beendet.if (Marshal.GetHRForException(ex) == -2146232800)Invoke(new Action(DoDisconnect));elseMessageBox.Show(ex.Message);}if (numRead > 0){strResponse = Encoding.ASCII.GetString(recvBuf, 0, numRead);tbResponse.Invoke(new Action(UpdateResponse));// Start reading from the network again.Remote.GetStream().BeginRead(recvBuf, 0, recvBuf.Length,ReadCallback, recvBuf);}} // End ReadCallbackNebenbei bemerkt kannst du dein Datenarray besser so initialisierenbyte[] array = new byte[] { 0x02, 0x00, 0x09, ... };Hajü
-
-
Hallo Hajü,
vielen Dank für deine Anwort und deine Bemerkung!
Ich hab immer noch das Problem mit der Rückmeldung des Server(des Geräts).Also ich weiß es nicht wie ich die 12 byte, die ich an dem Gerät schicke, lesen kann. also ich schcike 12 byte und soll auch nur 12 byte zurückkommen.
Hier habe ich das ganze Code was ich habe
Ich hoffe du oder ihr könnt mir weiterhelfen
private void cmdSendenEmpfangen_Click_1(object sender, EventArgs e)
{
try
{
ns = client.GetStream();
// hier schicke/schreibe ich 12 Byte in Networkstream
ns.Write(request(), 0, 12);
// hier möchte ich die 12 Byte, die das Gerät schickt, aus dem Networkstream lesen
//......
}
catch (Exception exp)
{
melde(exp.Message);
return;
}
}
public byte[] request()
{
byte[] array = new byte[12];
array[0] = 0x02;
array[1] = 0x00;
array[2] = 0x09;
array[3] = 0x03;
array[4] = 0x68;
array[5] = 0x01;
array[6] = 0x0E;
array[7] = 0x57;
array[8] = 0x00;
array[9] = 0x01;
array[10] = 0x03;
array[11] = 0x03;
return array;
}
}
}
- Bearbeitet Miele2008 Sonntag, 18. September 2011 15:34
-
Am 15.09.2011 14:34, schrieb Miele2008:> private void cmdSendenEmpfangen_Click_1(object sender, EventArgs e)> {> try> {> ns = client.GetStream();> // hier schicke/schreibe ich 12 Byte in Networkstream> ns.Write(request(), 0, 12);>> // hier möchte ich die 12 Byte, die das Gerät schickt, aus dem Networkstream lesen> //......> }Dazu brauchst du keinen TcpListener oder sowas, auch nicht deine eigeneIP Adresse, das geht ganz einfach mit Stream.Read(). Einen extra StartButton brauchst du auch nicht. Das ist sogenannte synchrone Übertragung,die funktioniert vielleicht erstmal, hat aber sonst nur Nachteile. Ambesten du vergisst, dass es sowas überhaupt gibt. Die Nachteile sind sozahlreich, dass sie diesen Artikel sprengen würden.Besser ist asynchron, nicht mit Read(...), sondern mit BeginRead(...)und einer CallBack() Funktion, so wie in meinem ersten Beispiel. DerCallback wird automatisch aufgerufen wenn Daten ankommen, das wird durchBeginRead(...) initiiert. Dabei musst du nur aufpassen, dass dabei unterder Haube ein neuer Thread erzeugt wird, in welchem du keinen Zugriffauf das UI hast. Wenn du im UI vom Callback aus was manipulieren willst,musst du über Invoke(...) gehen.Wenn du aber trotz aller Empfehlungen unbedingt bei synchron bleibenwillst, kannst du das so machen:private void cmdSendenEmpfangen_Click(object sender, EventArgs e){Byte[] recvBuf = new Byte[123];try{Byte[] array = new Byte[]{ 0x02,0x00,0x09,0x03,0x68,0x01,0x0E,0x57,0x00,0x01,0x03,0x03 };ns = Remote.GetStream();// hier schicke/schreibe ich 12 Byte in Networkstreamns.Write(array, 0, array.Length);// hier möchte ich die 12 Byte, die das Gerät schickt, aus demNetworkstream lesen//......int numRead = ns.Read(recvBuf, 0, recvBuf.Length);}Du kannst die Größe von Arrays überigens jederzeit zur Laufzeitbestimmen und auf deine magische '12' im Quelltext verzichten. Dasbringt irgendwann nur Probleme, glaub es. Für wirklich robusten Codefehlt hier allerdings noch 'ne Menge Exception handling;Hajü
- Als Antwort markiert Miele2008 Sonntag, 18. September 2011 15:37