PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Wie gehe ich sowas an? (.NET Client-Server Anwendung PDA<->Laptop)


Kennung Eins
2005-12-08, 14:21:24
Hallo,

ich habe einen Server (Laptop), der ist per AdHoc-WLAN an einen WinCE .NET 4.2 PDA Client verbunden. Die Netzwerkverbindung steht, das ist alles in Ordnung.

Ich suche jetzt Rat zu dem Thema, wie man folgende Problemstellung am günstigsten angeht:

Mein Server/Laptop sendet Daten an den PDA, der PDA (bzw meine WinCE-Anwendung) wertet diese Daten aus. Es sollen simple Zahlenketten übertragen werden, die WLAN-Bandbreite wird kaum belastet (1-2kb/s).

Ich habe bisher weder mit .NET noch mit einer anderen Programmiersprache eine Netzwerksoftware entwickelt.

Womit fange ich an, wie würde solch eine Softwarearchitektur grob aussehen?

Vielen Dank für eure Hilfe :)

Monger
2005-12-08, 14:46:05
Ich geb einfach mal ungefragt meinen Senf dazu ab:


Das erste Problem was sich dir stellt ist, dass beide Kommunikationspartner über eine gemeinsame Basis verfügen müssen, um sich überhaupt verstehen zu können. Dazu schreibst du geschickterweise ein Interface, was mindestens die Deklarationen aller notwendigen Methoden beinhaltet, und darüber hinaus "Paket" Klassen, die serialisierbar sind.

Wenn man weiß dass Server und Client das selbe Interface implementieren, kann der Client Anfragen auf eben diese Methoden des Interfaces absetzen. (Ich habs mal gemacht, habs aber nicht mehr im Kopf. Irgendwie konnte .NET da gewissermaßen eine Verbindung zu eben diesem Objekt aufbauen)

Die zweite Frage die sich dir stellt ist: wann und wie sollen denn die Partner überhaupt miteinander kommunizieren?
Bleibt die Verbindung so lange offen, bist du sie von Hand schließt? Oder schaut der PDA regelmäßig nach, ob es auf dem Rechner was neues gibt? Weil üblicherweise hat man eine Client/ Server Architektur, d.h. der eine erbittet eine Verbindung während der andere ständig auf neue Anfragen lauscht. Der Server kann normalerweise nicht den Client auffordern, eine neue Verbindung zu ihm aufzubauen - er muss warten bis sich der Client freiwillig wieder bei ihm meldet.


Du tust dir natürlich leichter, wenn du auf bestehender Technik aufsetzst. Ich hab da noch irgendwas von SOAP in Erinnerung, kann dir aber leider keine Details mehr nennen...

Shink
2005-12-08, 15:09:36
Ich würds so machen: TCP-Socket-Verbindung (Etwas "Googlen" sollte reichen): Der Laptop macht einen Socket an einem bestimmten Port auf und wartet auf Verbindungen. Der PDA schickt ein Request in bestimmter Form; der Laptop parst alle eingehenden Nachrichten nach so einem Request und sendet dann Daten - entweder einzeln (eine Antwort pro Request) oder er schickt bis der Clientprozess am PDA gestorben ist (was er dank einem Timeout herausfindet)

ScottManDeath
2005-12-08, 15:58:49
Entweder von Hand mit Sockets&co, oder bequemer, möglicherweise langsamer mit .NET Remoting. Wie zuvor beschrieben, kannst Du dann Methoden ausführen, von Objekten, die auf einem anderen Rechner sich befinden.

MuLuNGuS
2005-12-08, 16:03:53
hi,

du brauchst eine instanz der classe "TCPClient" oder "UDPClient" je nach dem wie sicher die daten ankommen sollen, TCP-verbindungsorientiert, UDP-nicht-verbindungsorientiert(also ohne rückantwort).

dann noch eine instanz der klasse "IPEndPoint" welche mit ip-adresse und port gefüttert werden.

außerdem sollten senden und empfangen in einen seperaten thread gelegt werden sonst "hängt" die anwendung in der zeit in der es auf daten wartet oder eben versendet.

das ist natürlich nicht alles, aber wenn du mit derartigen stichworten googlest solltest du einige samples finden.

ein blick in den namespace System.Net u. System.Net.Sockets lassen auch schon einiges erahnen.

viel spaß ;)

Kennung Eins
2005-12-09, 16:53:23
Danke Leute :) Wenn sich fragen ergeben, melde ich mich wieder.

[edit]
ach so, gleich eine Frage: wie emuliere ich denn die Kommunikation zwischen PDA und Server? Denn wenn ich mein Prog ausführe ist der PDA nicht am gleichen Rechner. (das läuft alles auf einem separaten System und muss immer erst mittels Stick/Diskette auf den Laptop gebracht werden. Ich kann also nicht schnell "mal eben" kompilieren und das Ganze laufen lassen. Sprich: mein Entwicklungsrechner ist nicht der Rechner, auf dem das später laufen soll.)

Monger
2005-12-09, 17:21:55
Danke Leute :) Wenn sich fragen ergeben, melde ich mich wieder.

[edit]
ach so, gleich eine Frage: wie emuliere ich denn die Kommunikation zwischen PDA und Server? Denn wenn ich mein Prog ausführe ist der PDA nicht am gleichen Rechner. (das läuft alles auf einem separaten System und muss immer erst mittels Stick/Diskette auf den Laptop gebracht werden. Ich kann also nicht schnell "mal eben" kompilieren und das Ganze laufen lassen. Sprich: mein Entwicklungsrechner ist nicht der Rechner, auf dem das später laufen soll.)

Im Prinzip sollte imo eine .NET Anwendung auch auf Windows CE laufen. Testen kannst du sie deshalb imho im Prinzip ganz genauso auf einem normalen Rechner. Und normalerweise finden sich zwei Anwendungen ja über den Socket, also IP plus Port. Auf dem selben Rechner kannst du 127.0.0.1 ansprechen, um eine rechnerinterne Kommunikation über TCP/IP umzusetzen.

Das schließt natürlich nicht alle Probleme aus die in einem Netzwerk auftreten können, aber zum testen und entwickeln sollte das reichen.

Kennung Eins
2005-12-09, 18:37:16
Das scheint ja echt viel einfacher zu sein, als ich gedacht habe. Erinnere mich da noch (ungern) an CPP- und Delphi-Zeiten, das war irgendwie komplizierter. Ich finds ja lustig, daß der WinCE-Emulator mit dem Basisrechner (auf dem VS.NET läuft) kommunizieren kann. Da drauf läuft meine Anwendung schon.

Wenn ichs jetzt aber auf den PDA kopiere und wirklich mit den realen Geräten arbeite, kriege ich auf PDA-(Client-)Seite ne Fehlermeldung. (irgendwas mit "assembly not found", bin inzwischen nicht mehr auf Arbeit) Aber das wird hoffentlich ja hinzukriegen sein :)

Demirug
2005-12-09, 18:54:55
Den richtigen Kompakt Framework auf dem PDA?

Kennung Eins
2005-12-09, 21:56:36
Kann man das Updaten? Hab nur das drauf, was der Hersteller mitgeliefert hat ...

grakaman
2005-12-09, 21:59:35
Du hast doch jetzt Remoting genommen oder?! Da hast du doch aber auch nicht vergessen, die Interfaces (oder schlechtenfalls die ganze Implementierung), die man für gewöhnlich in eine eigene Assembly packt, mit rüberzukopieren?!

Demirug
2005-12-09, 22:33:34
Kann man das Updaten? Hab nur das drauf, was der Hersteller mitgeliefert hat ...

Ja normalerweise gibt es Updates. welchen Visual hast du benutzt und welche OS Version ist auf dem PDA?

Demirug
2005-12-09, 22:34:54
Das scheint ja echt viel einfacher zu sein, als ich gedacht habe. Erinnere mich da noch (ungern) an CPP- und Delphi-Zeiten, das war irgendwie komplizierter. Ich finds ja lustig, daß der WinCE-Emulator mit dem Basisrechner (auf dem VS.NET läuft) kommunizieren kann. Da drauf läuft meine Anwendung schon.

Mit Indigo bzw. WCF ist sowas IMHO sogar noch einfacher. Leider wird es das vorerst nicht für die PDAs geben.

Kennung Eins
2005-12-12, 10:54:37
Ja normalerweise gibt es Updates. welchen Visual hast du benutzt und welche OS Version ist auf dem PDA?Ich benutze VS.NET 2003 und "WinCE 4.2 .NET Pro Plus" (so stehts auf dem Microsoft-Aufkleber hinten am PDA). Sauge mir grad alles, was ich an Updates finden kann.

Diese ganzen "Windows CE .NET 4.2 Platform Builder Quarterly Update Package" Dinger, brauche ich die eigentlich? Oder nur das CF SP3? Naja, ich lade erstmal alles runter. Mal sehen, wie ich das alles installiert bekomme, weil sich kein Kabel für USB (ActiveSync) auftreiben lässt. (über WLAN geht das sicherlich nicht, oder?)
Du hast doch jetzt Remoting genommen oder?! Da hast du doch aber auch nicht vergessen, die Interfaces (oder schlechtenfalls die ganze Implementierung), die man für gewöhnlich in eine eigene Assembly packt, mit rüberzukopieren?!Ich hab einfach mal eine TestApp geschrieben, die nur TcpListener und TcpClient benutzt. Darauf kann ich dann ja aufbauen, wenn das auf meinem PDA mal läuft.


P.S.: Ich finds ja seltsam, daß es noch keine XScale-optimierte .NET CF Version gibt ...

Monger
2005-12-12, 12:01:24
Mit Indigo bzw. WCF ist sowas IMHO sogar noch einfacher. Leider wird es das vorerst nicht für die PDAs geben.

Gibt es das denn schon für WinXP ?!?
Ich meine, ist Indigo im aktuellen Visual Studio schon ein Thema?

Kennung Eins
2005-12-19, 13:09:35
Also ist schon echt seltsam. Habe das .NET Compact Framework SP3 nun drauf, und dennoch keine Besserung.

Hat jemand hier eine Idee dazu?

[edit]
Code.

Der Client (WinCE):

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);
client.Close();
Server (WinXP):
IPAddress localAddr = IPAddress.Parse(s);
TcpListener server = new TcpListener(localAddr, port);
server.Start();
Byte[] bytes = new Byte[256];
String data = null;
while(true)
{
Console.Write("Waiting for a connection... ");
TcpClient client = server.AcceptTcpClient();
Console.WriteLine("Connected!");
data = null;
NetworkStream stream = client.GetStream();
int i;
while((i = stream.Read(bytes, 0, bytes.Length))!=0)
{
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
Console.WriteLine(String.Format("Received: {0}", data));
data = data.ToUpper();
byte[] msg = System.Text.Encoding.ASCII.GetBytes(data);
stream.Write(msg, 0, msg.Length);
Console.WriteLine(String.Format("Sent: {0}", data));
}
client.Close();
}Er bricht jeweils beim erstellen des TcpClient- bzw TcpListener-Objekts ab.

Demirug
2005-12-19, 15:23:49
Gibt es das denn schon für WinXP ?!?
Ich meine, ist Indigo im aktuellen Visual Studio schon ein Thema?

Natürlich. Man muss nur das WinFX SDK aufspielen. Ist halt noch Beta.

Demirug
2005-12-19, 15:26:53
Also ist schon echt seltsam. Habe das .NET Compact Framework SP3 nun drauf, und dennoch keine Besserung.

Hat jemand hier eine Idee dazu?

Resource Assembly hört sich irgendwie nach lokalisierung an. Am besten mal die Exeception fangen und die Details ausgeben.

Kennung Eins
2005-12-20, 11:05:17
OMG. Ist fast schon peinlich, das zu erzählen: Ich hab einfach nur die .EXE auf den PDA kopiert, aber kein .CAB erstellt. Wußte nicht, daß der dann erst die entsprechenden DLLs mitbringt. Thx Demi.

Dafür krieg ich jetzt folgenden Fehler:
SocketException: System.Net.Sockets.SocketException: No such host is known

Ich gebe eine IP-Adresse an, die ich vom PDA aus auch direkt anpingen kann. Warum findet meine Applikation das dann nicht?! Naja, krieg ich schon noch raus.

Monger
2005-12-20, 11:31:17
Auf welchem Port läuft denn die Serverapplikation?

Manchmal will ein bestimmter Port einfach nicht, dann muss man halt einen anderen ausprobieren.

Kennung Eins
2005-12-20, 12:18:03
habs erst auf 13000 und jetzt auf 81 probiert :-/

ahh ... eh.. Firewall? Mal überprüfen.

[edit]
hmm nee wars dorch nicht. Komische Sache.
Unglaublich: direkt mit der IP-Adresse gehts nicht (wie gesagt, anpingen kann ich sie!) aber mit dem netzwerknamen klappts?!

Monger
2005-12-20, 13:28:45
Kannst du mal den Code posten, wo du Client und Server an den Socket bindest? Sollten ja nur ein paar Zeilen sein...

Ich kann an deinem geposteten Code nicht erkennen, wo du IP und Port beim Client angibst.

Kennung Eins
2005-12-20, 16:20:46
ok, das hier ist das original. Dabei funktioniert es nur, wenn ich den Netzwerknamen angebe.
[edit]
im String server steckt die IP-Adresse! Ich übergebe also in den String "141.1.1.11", zum Beispiel. Oder eben "rechnername".

static void Connect(String server, String message)
{
try
{
Int32 port = 81;

TcpClient client = new TcpClient(server,port);

(...)
}
}


Und das hier ist meine neueste Kreation. Die funktioniert gar nicht.

static void Connect(String server, String message)
{
try
{
Int32 port = 81;

IPAddress ipa = IPAddress.Parse(server);
IPEndPoint ipe = new IPEndPoint(ipa,port);
TcpClient client = new TcpClient(ipe);

(...)
}
}

Bei dem letzten Sagt er "Die angeforderte Adresse ist in diesem Kontext ungültig". Was soll das heissen, in diesem Kontext? Die Adresse IST gültig. grrr

Der Server läuft übrigens so:
[edit]
Auch hier steckt im String s die IP-Adresse.

Int32 port = 81;
IPAddress localAddr = IPAddress.Parse(s);

//TcpListener server = new TcpListener(port);
TcpListener server = new TcpListener(localAddr, port);

server.Start();


Zusammenfassung:

TcpListener braucht eine IP-Adresse und TcpClient braucht einen Netzwerknamen als Parameter. (:o)

Shink
2005-12-23, 08:10:28
"lustig", aber bei mir ist das mit dem DNS-Eintrag genauso.
Bei mir funktioniert dein Code zum Empfangen übrigens überhaupt nicht; kann das sein das das Read() blockiert, bis genug Daten da sind?

Bei mir siehts jetzt übrigens so aus:

public void connect()
{
codeLine = "";
IPHostEntry ipHostEntry = Dns.Resolve(server);
IPAddress ip = ipHostEntry.AddressList[0];
IPEndPoint ep = new IPEndPoint(ip, port);
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Connect(ep);
}

public void readFromSocket()
{
log.Debug("Starting read process.");
buffer = new byte[128];
int available = 0;

do
{
available = Math.Min(socket.Available, buffer.Length);
if (available > 0)
{
socket.Receive(buffer, 0, available, SocketFlags.None);
lineRead(buffer, available);
}
else
{
System.Threading.Thread.Sleep(100);
}
} while (active);

}

grakaman
2005-12-23, 10:55:44
So hab ichs immer gemacht...

IPHostEntry ipHostInfo = Dns.Resolve(this._serverName);
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint remoteEP = new IPEndPoint(ipAddress, this._serverPort);

Socket client = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);

client.Connect(remoteEP);

Kennung Eins
2005-12-23, 13:57:33
kann das sein das das Read() blockiert, bis genug Daten da sind?Hi, nein, eigentlich nicht :|

Schon seltsam.

Was für Vorteile hat es, direkt mit den Sockets zu arbeiten (also ohne TcpListener / TcpClient)?