German Client for MPD

mamuen

Member
Licensed User
Hallo Zusammen,

bin neu hier und auch neu was das Programmieren mit B4PPC angeht.
Ich habe einen VPA compact II mit .net 1 SP3. Bei einigen Demos bekomme
ich immer die Fehlermeldung "Die Assembly der Ressouce konnt nicht gefunden
werden". Was mache ich falsch? Ich habe schon die ganzen Threads durchgelesen
und nichts gefunden, was mir weiter helfen könnte.

Doch nun zu meinem Projekt:
MPD ist ein Serverprogramm welches man über eine Socketverbindung steuern kann.
Es werden einfache Textbefehle z.B. per WLan/Kabel/Bluetooth
übertragen. Der Server spielt dann das gewält Lied ab. (www.mpd.org)

Ich möchte nun zuerst eine Art Fernsteuerungsprogramm erstellen, welches erst
eine IP-Verbindung zum Server aufbaut(IP:port) und mir die Möglichkeit gibt per
Texteingabe Befehle zu senden und die Antwort als Text auszugeben.

Erste Versuche habe ich schon gestartet, sind aber kläglich gescheitert.
Siehe oben. Über ein paar Tips oder ein Programmgerüst (fals nicht zuviel verlangt)
würde ich mich sehr freuen.

Grüße Mamuen
 
Last edited:

alfcen

Well-Known Member
Licensed User
Hallo Mamuen,

mit einem Programmgeruest kann ich ad hoc nicht aushelfen.

Generell benoetigst Du .NET Compact Framework Version 2.0 um
Programme ins Laufen zu bringen. Einige Libraries erwarten 2.0,
der Optimized Compiler in jedem Fall.

www.mpd.org fuehrt zum Montgomery Police Department, Alabama.
 

mamuen

Member
Licensed User
Sorry,
das war ein alter Link!
richtiger Link www.musicpd.org

Ich habe es auch mit .Net 2.0 CF ausprobiert und die zugehörigen DLLs waren
auch impassenden Verzeichnis. Leider die selbe Fehlermeldung!

Ich hab noch ein bischen rumgespielt. Kann es sein, dass die Fehlermeldung auf die nicht gefundene Ressource auch bedeuten kann, dass der Server nicht gefunden wird?

Gruß Mamuen
 

alfcen

Well-Known Member
Licensed User
Kann es sein, dass die Fehlermeldung auf die nicht gefundene Ressource auch bedeuten kann, dass der Server nicht gefunden wird?
Hmm, eigentlich nicht. Hast Du mit optimized kompiliert? Falls nicht, hast Du
xxxxxx.exe.config auf den pocket pc kopiert?
 

mamuen

Member
Licensed User
Hi alfcen,
ich compiliere mit Version 5.5 und es wurde keine xxxxx.exe.config erzeugt. Wo
stellt man optinized code ein?

Habe mal das Prog Dict oder so änlich aus einem anderen Thread laufen lassen.
Mit aktiv sysnc komme ich ins Internet und bekomme eine Übersetzung. Ist
aber mein USB-Kabel abgezogen bekomme ich die selbe Fehlermeldung.
 

specci48

Well-Known Member
Licensed User
Hallo mamuen,

ich compiliere mit Version 5.5 ...
O.K. damit sieht die Sache wieder etwas anders aus. In der Version 5.5 gibt es (noch) keinen "optimized compile", denn der steht erst ab der Version 6 zur Verfügung.:sign0161:

Ein mit Version 5.5 erzeugtes .exe läuft zunächst auf der Basis .Net CF 1.

Damit ein Programm (z.B. MyApp.exe) die Funktionen des .Net CF 2 verwendet, muss die Datei "Dbasic.exe.config" aus dem Installationspfad von Basic4ppc in den gleichen Pfad von "MyApp.exe" kopiert werden. Diese Kopie ist dann in "MyApp.exe.config" umzubenennen.
Vorraussetzung hierbei ist natürlich, dass Du auf Deinem Device ein .Net CF 2 installiert hast... ;)

Sofern also ein Programm zwingend komponenten von .Net CF 2 verwendet, sind sie auf Deinem VPA compact II mit .net 1 SP3 nicht lauffähig. Sofern Du in den vollen Genuß aller (derzeitgen) Möglichkeiten von Basic4ppc kommen möchstest, bleibt Dir der (kostenlose) Upgrade auf .Net CF 2 nicht erspart.
http://www.microsoft.com/downloads/details.aspx?familyid=AEA55F2F-07B5-4A8C-8A44-B4E1B196D5C0&displaylang=en


Viele Grüße

specci48
 

mamuen

Member
Licensed User
Hallo specci,

danke für deine ausführliche und kompetente Antwort, jetzt ist mir einiges klarer
geworden. Tja, am Anfang ist die Lernkurve etwas steiler!

Aber nun komme ich zu einer anderen Frage, setzt die Network.dll nur auf TCP
oder auch auf UDP auf und brauche ich um die Network.dll einzusetzen eine
.Net 2 Umgebung auf meinem Device? Es steht nichts in der Hilfe darüber.

Gruß Mamuen
 

specci48

Well-Known Member
Licensed User
Hi Mamuen,

bisher habe ich (noch) nicht mit der Network.dll gearbeitet und meine Netzwerk-Kenntnisse sind auch eher beschränkt. :sign0013:

Sofern eine Dll .Net CF 2 benötigt, wird i.d.R. in der Hilfe unter dem Stichwort "overview" darauf hingewiesen (siehe z.B. die outlook.dll). Daher bin ich mir sicher, dass hier .Net CF 1 ausreicht.

Weiter heißt es in der Hilfe
It uses the TCP protocol.
daher nehme ich an, dass UDP nicht unterstützt wird. :(



Gruß

specci48
 

alfcen

Well-Known Member
Licensed User
Danke fuer die Uebernahme, specci48.
Hier sind es 8 Stunden spaeter als bei Euch :)

Mamuen, empfehle B4PPC Ver 6.05 zu installieren. Sie generiert ein
'MyApp.exe.config' automatisch wenn ohne Optimierung kompiliert wird.
 

mamuen

Member
Licensed User
Hi,
danke an alle.

Die Info war gut, denn MPD setzt für die Kommunuikation zwischen Client und
Server TCP als Übertragungsprotokoll ein. Somit kann ich vom Sofa aus meine
Stereoanlage fernsteuern und kann die Musik genießen ohne mich bewegen zu
müssen.

Gruß Mamuen
 

mamuen

Member
Licensed User
... netter Trick: man zieht nach Okinawa und ist dann seiner (Ursprungs-)Zeit immer ein wenig voraus ... ;)
Ok, Ok man kanns ja mal versuchen ;-)

Ich hab jetzt meine ersten gehversuche hinter mir. Auf meinem LinuxSoundserver
läuft der MPD-Dämon und mittels TCPDump überwache ich die WLanschnittstelle.

Nachdem ich eine Verbindung mittels meines Progs aufzubauen versuche, sehe
ich in TCPDump ein von mir gesendetes IP-Paket. Dieses wird mehrmals gesendet
aber es kommt zu keinem Verbindungsaufbau (3-Wegehandshake bei TCP). Die
Firewall ist ausgeschaltet. Per Webbrowser bekomme ich aber Zugriff auf die
Linuxbüchse.

Tja, da bleibt nur noch die eigene Unfähigkeit (Programmierkunst) übrig.
Ich versuch mal mein Prog anzuhängen und hoffe, dass einer einen Fehler
findet.

Gruß Mamuen
 

mamuen

Member
Licensed User
Hi,

ich habe eine kleine Erfolgsmeldung zu berichten, nachdem ich den Port von 6600
auf 80 geändert habe, bekam ich keine Fehlermeldung mehr (Resssource konnte
nicht mehr gefunden werden). Statt dessen bekam ich natürlich Fehlermeldungen
von meinem Webserver.

Werde wohl noch ein Bischen mit dem Protokoll von MPD experimentieren
müssen.

Gruß mamue
 

brathbone

Member
Licensed User
Forgive the response in english. I don't speak German, but I may be able to help.

MPD server listens on TCP port 6600

When you send commands, you must append CHR(13) to the end of the command.

Responses from MPD server will also be terminated with CHR(13)

I don't have MPD, so code below is untested.

Try something like this:

Sub Globals
Dim IP(0) As String
Dim bufferbits(0) As byte
End Sub

Sub ButtonConnect_Click

Dim IP(0) As String
IP() = Client.GetIP(textboxip.Text)
'client = network.dll client
client.Connect(IP(0),6600)
'stream = binaryfile object
stream.New1(client.GetStream,false)
label1.Text = "Connection established."
timer1.Enabled = true
'//issue the "next" command
stream.WriteBytes (stream.StringToBytes("next" & CHR(13)) )
End Sub

Sub Timer1_Tick
If client.DataAvailable = true Then
Dim bufferbits(4096) As byte
count = stream.ReadBytes(bufferbits(),4096)
buffer = bit.BytesToString(bufferbits(),0,count)
'show server response
label1.Text = buffer
End Sub

Best wishes,
 

mamuen

Member
Licensed User
Hi brathbone,

Thanke you for your interest. I have check it at
http://mpd.wikia.com/wiki/MusicPlayerDaemonProtocolOutline

There you can read:
"The client transmits a command sequence, terminated by a newline."
"Each server response ends with a completion code. There are two codes: OK and ACK."

My problem is now, the prog. reads only about 33600 bytes not the whole stream.
By the next trasmitted newline the prog. will receive the rest.


Sub Globals
'Declare the global variables here.
Dim bufferbits(0) As byte
End Sub

Sub App_Start
Form1.Show
End Sub

Sub btnSetSRV_Click
bit.New1
client.New1
client.Connect ("192.168.200.1",6600)
stream.New1(client.GetStream,false)
Do While client.DataAvailable = false
Loop
Dim bufferbits(128) As byte
count = stream.ReadBytes(bufferbits(),128)
buffer = bit.BytesToString(bufferbits(),0,count)
txtAntwort.Text = buffer
Label5.Text = "Connected to 192.168.200.1:6600"
Form2.Show
End Sub

Sub btnSend_Click
stream.WriteBytes (stream.StringToBytes(txtBefehl.Text & Chr(10)) )
timer1.Enabled = true
End Sub

Sub Timer1_Tick
If client.DataAvailable = true Then
Dim bufferbits(102400) As byte
count = stream.ReadBytes(bufferbits(),102400)
buffer = bit.BytesToString(bufferbits(),0,count)
buffer = StrReplace (buffer,Chr(10),crlf) 'linefeed to crlf
txtAntwort.Text = buffer
txtcount.Text = count
End If
timer1.enabled = false
txtBefehl.Focus
End Sub

Sub btnExit_Click
client.Close
AppClose
End Sub



Best wishes, Mamuen
 

brathbone

Member
Licensed User
mamuen,

Thanks for reminding me that I have to be more careful about waiting for all the data to arrive.

So let's say the server sends two commands like:

220 then a bunch of other text & CRLF
240 something else & CRLF


We might get "220 then" when we check for incoming data, and then we might get "a bunch of other text" & chr(13) & chr(10) & "240 Something el"
and then might get "se" & chr(13) & chr(10) on our next check.

The trick here is going to be to use a global variable to store our incomplete commands between checking for data. Then when we check for data, we check to see if there is a terminator in it (chr(13) & chr(10)) using something like:

If StrIndexOf(stringbuffer,chr(13) & chr(10),0) > -1

We can't assume that the terminator is the last part of our data, since we may have received part of the next message as well, so if there is a terminator, take everything before the terminator, append it to whatever may have come in before (our global variable) and then act accordingly. Of course we need to look for additional terminators or partial data before proceeding.

If we don't have a terminator, then append the data to our global variable. I don't have this code written in Basic4PPC yet, but here is pseudo-code based on what my REALbasic code does:

count = stream2.ReadBytes(bufferbits(),8192)
stringbuffer = bit.BytesToString(bufferbits(),0,count)

'//look for a terminator in our new data
i = StrIndexOf(stringbuffer,CHR(13) & CHR(10),0)

if i > -1 then
'//loop though and process commands until we run out of terminators
do while i > -1

'//parse out everything before the first terminator
'//append it to any existing data in our global variable
'//process the command

'//look for additional terminators in existing data
i = StrIndexOf(stringbuffer,CHR(13) & CHR(10),i)
loop

else
'//no terminator in this batch of data
'//append text to global variable and wait for more data.

end if

hope that helps,
 

mamuen

Member
Licensed User
Hi brathbone,

your way i think is the clean way. I found a other solution (quick and dirty), but it works. The endstring of transmision is always "OK"+crlf.


endstr = 0
Dim bufferbits(4096) As byte
If client.DataAvailable = true Then
Do
count = stream.ReadBytes(bufferbits(),4096)
buffer = bit.BytesToString(bufferbits(),0,count)
buffer = StrReplace (buffer,Chr(10),crlf) 'linefeed to crlf

If SubString (buffer,StrLength(buffer)-4,2)="OK" Then
endstr = 1
Else If SubString (buffer,0,3)="ACK" Then
endstr = 2
End If

txtAntwort.Text = txtAntwort.Text & buffer
Loop While endstr = 0
txtcount.Text = endstr
End If



Regards manuen
 
Top