Hey mensen, beetje rustig hier in de NLDMSNP sectie. Tijd voor wat nieuwe code dacht ik maar.
Ik ben bezig geweest met FileTransfer via NLDMSNP, jaja en het werkt voor het grootste deel.
De rest wordt vast door iedereen hier op het forum wel opgelost hoop ik .
{En natuurlijk hopen dat Jelmer tijd en zin heeft om het te implementeren. Ik heb niet veel verstand van
component-bouw dus als ik ermee bezig zou gaan, zou het waarschijnlijk gigantisch onstabiel worden.}
Ik moet er even bij zeggen dat ik alles op 1 pc had draaien en heb dus op die manier alles getest.
Dus mijn eigen client en de Microsoft client.
Maar goed genoeg gekletst.
Als iemand vanuit de Microsoft messenger een bestand naar je wil versturen krijg je het volgende binnen:
Code:
Header: MIME-Version: 1.0
Content-Type: text/x-msmsgsinvite; charset=UTF-8
Content: Application-Name: Bestandsoverdracht
Application-GUID: {5D3E02AB-6190-11d3-BBBB-00C04F795683}
Invitation-Command: INVITE
Invitation-Cookie: 391884
Application-File: Test.txt
Application-FileSize: 13
Connectivity: U
Die kan je vervolgens accepteren met het volgende:
Code:
MIME-Version: 1.0
Content-Type: text/x-msmsgsinvite; charset=UTF-8
IP-Address: xxx.xxx.xxx.xxx
IP-Address-Internal: xxx.xxx.xxx.xxx
Port: 6891 //Wordt standaard door de Microsoft client gebruikt, dus ik gebruik die ook maar.
PortX: 11178 //Wordt standaard door de Microsoft client gebruikt, dus ik gebruik die ook maar.
AuthCookie: 544120 //Wordt straks weer gebruikt in het MSNFTP gedeelte.
Sender-Connect: TRUE
Invitation-Command: ACCEPT
Invitation-Cookie: 391884 //Zelfde als die je ontvangen hebt.
Launch-Application: FALSE
Request-Data: IP-Address:
Om een of andere reden kon ik niet d.m.v een idTCPclient connecten met de Microsoft client, vandaar dat ik een Sender-Connect: TRUE stuur.
Dit houd in dat ik zelf een idTCPServer start en zo de Microsoft messenger met mij laat connecten. Dit werkt om een of andere
reden wel.
Je stuurt dan dus je ip adres en je interne ip adres. (als je bijv. een thuisnetwerk hebt, maar ze kunnen ook hetzelfde zijn)
Vervolgens connect de Microsoft client met jouw server.
(Dit deel van de communicatie heb ik bijna rechtstreeks van http://www.hypothetic.org/docs/msn/ gehaald).
Maargoed, als de Microsoft client geconnect heeft,
Stuur je vanaf de server bij de onconnect:
En dan krijg je hetzelfde terug.
Vervolgens stuur je:
Code:
USR mijnemail@hotmail.com 544120 // Het getal aan het eind is het AuthCookie, die verzonden werd tijdens de invitation.
dan krijg je de Filesize terug
Vervolgens stuur je:
En dan krijg je de data van het bestand binnen in pakketjes
Elk pakketje bestaat uit een header en een body. De officiele client stuurt body's van 2045 bytes.
De header bestaat uit 3 bytes. De eerste is altijd 0, bij het laatste pakketje zou die 1 moeten zijn volgen hypothetic,
maar das dus niet zow. De 3e byte is de grootte van de body / 256, en byte 2 is de rest. Dus bij een volledig pakket
van 2045 bytes is de header 0,253,7.
Om de ontvangen pakketjes weer om te zetten naar een bestand gebruikt ik het volgende in de OnExecute van de server:
Code:
while AThread.Connection.Connected do
begin
AThread.Connection.ReadBuffer(HeaderByte1,1);
AThread.Connection.ReadBuffer(HeaderByte2,1);
AThread.Connection.ReadBuffer(HeaderByte3,1);
AThread.Connection.ReadStream(TestStream,(HeaderByte3*256)+HeaderByte2,false);
if ((HeaderByte3*256)+HeaderByte2) <> 2045 then // Dan was dit het laatste blok.
begin
AThread.Connection.WriteLn('BYE 16777989'); // Dan weet de zender dat het aangekomen is.
Teststream.Free;
end;
end;
En dit was het ontvangst gedeelte.
Ik heb dit op mijn pc getest, de 2 clients naast elkaar draaiend.
En dit gedeelte werkt helemaal, ik heb bestanden verzonden van 13 bytes tot 800 MB.
Alleen als iemand anders mij een bestand stuurde kon ik hem wel accepteren maar vervolgens connecte zijn client niet
met mijn server. Dus waar dat nou aan ligt weet ik nie, maar er zijn vast wel mensen die hier een oplossing voor hebben.
Het verzenden van bestanden gaat bijna hetzelfde.
Dit is het invitation gedeelte.
Verzend de invitation:
Code:
MIME-Version: 1.0
Content-Type: text/x-msmsgsinvite; charset=UTF-8
Application-Name: Bestandsoverdracht
Application-GUID: {5D3E02AB-6190-11d3-BBBB-00C04F795683} //Deze is altijd hetzelfde
Invitation-Command: INVITE
Invitation-Cookie: 12345
Application-File: Test.txt
Application-FileSize: 13
Connectivity: U
Dan krijg je als de ontvanger accepteert het volgende terug:
Code:
Header: MIME-Version: 1.0
Content-Type: text/x-msmsgsinvite; charset=UTF-8
Content: Invitation-Command: ACCEPT
Invitation-Cookie: 12345
Launch-Application: FALSE
Request-Data: IP-Address:
Dit beantwoord je met dit:
Code:
MIME-Version: 1.0
Content-Type: text/x-msmsgsinvite; charset=UTF-8
Invitation-Command: ACCEPT
Invitation-Cookie: 12345
IP-Address: xxx.xxx.xxx.xxx
IP-Address-Internal: xxx.xxx.xxx.xxx
Port: 6891
PortX: 11178
AuthCookie: 54321
Launch-Application: FALSE
Request-Data: IP-Address:
En vervolgens connect de Microsoft client met de idTCPServer.
Dan krijg je een paar dezelfde regels als bij het ontvangen, maar nu zijn de rollen omgedraait.
En na het TFR command te hebben ontvangen stuur ik met de volgende procedure de data.
Code:
var HeaderByte1, HeaderByte2, HeaderByte3 : Byte;
Packets, LeftOver, i : integer;
begin // In de bestandStream zit het te versturen bestand.
if BestandStream.Size < 2045 then // Als er maar 1 pakketje is, bij een heel klein bestand.
begin
HeaderByte1 := 0;
HeaderByte2 := BestandStream.Size mod 256;
HeaderByte3 := BestandStream.Size div 256;
Client.Connection.WriteBuffer(HeaderByte1,1);
Client.Connection.WriteBuffer(HeaderByte2,1);
Client.Connection.WriteBuffer(HeaderByte3,1);
Client.Connection.WriteStream(BestandStream,true,false,BestandStream.Size);
end
else
begin //Kijken hoeveel pakketjes er zijn en wat de rest is.
LeftOver := BestandStream.Size mod 2045;
Packets := BestandStream.Size div 2045;
for i := 0 to (Packets-1) do //Voor alle hele pakketjes.
begin
HeaderByte1 := 0;
HeaderByte2 := 253; //Deze headerbytes zijn voor al deze pakketjes natuurlijk hetzelfde.
HeaderByte3 := 7;
Client.Connection.WriteBuffer(HeaderByte1,1);
Client.Connection.WriteBuffer(HeaderByte2,1);
Client.Connection.WriteBuffer(HeaderByte3,1);
Client.Connection.WriteStream(BestandStream,false,false,2045);
end;
HeaderByte1 := 0; //En dan nog het laatste pakketje.
HeaderByte2 := LeftOver mod 256;
HeaderByte3 := LeftOver div 256;
Client.Connection.WriteBuffer(HeaderByte1,1);
Client.Connection.WriteBuffer(HeaderByte2,1);
Client.Connection.WriteBuffer(HeaderByte3,1);
Client.Connection.WriteStream(BestandStream,false,false,LeftOver);
end;
end;
En dit verzenden gaat goed bij pakketjes tot ongeveer 65 kB. Ik heb ook een bestand van 93 kB geprobeerd maar dan krijg ik
een acces violation. Misschien dat de buffer dan vol zit, of dat ik moet wachten tot de ontvanger het pakketje binnen heeft,
maar ik krijg niet na elk pakketje een acknowledge dus heb geen idee hoe ik dit moet oplossen.
Als de ontvanger het dus goed ontvangen heeft krijg je nog een:
Ik hoop dat Jelmer, of iemand anders natuurlijk, hier wat mee kan en het misschien kan implementeren in het NLDMSNP component.
En als men nog oplossingen heeft voor bovengenoemde problemen dan hoor ik dat graag.
En prettige vakantie gewenst allemaal natuurlijk
Gr. Erwin
Bookmarks