Résumé de l'article :
Delphi est puissant. L'écriture de logiciels avec Delphi peut considérablement raccourcir le cycle de développement logiciel. Cet article explique comment utiliser Delphi pour écrire un programme de transfert de fichiers point à point.
-----------------------------------------------
Delphi est puissant. L'écriture de logiciels avec Delphi peut considérablement raccourcir le cycle de développement logiciel. L'idée de base du transfert de fichiers point à point est qu'un logiciel serveur et un logiciel client utilisent le même port. Après avoir été connecté, le client envoie une requête au serveur, comprenant le nom du fichier, la taille, etc. le fichier à transférer. Si le serveur accepte et commence à transférer les fichiers. Bien entendu, il existe deux modes de transfert de fichiers, le code ASCII et Bin, mais généralement Bin suffit. Sur la base de la discussion ci-dessus, à l'origine, cela pouvait être fait en utilisant les contrôles NMStrum et NMStrumServ de Delphi4, mais je l'ai testé et j'ai constaté que le contrôle NMStrum peut toujours être utilisé pour des fichiers plus petits et est très pratique, mais si le fichier est volumineux (1 Mo) , une erreur se produira. Nous utilisons donc ensuite TServerSocket et TClientSocket dans Delphi pour écrire ce programme. En raison de la limitation de la taille des paquets Ethernet et du mécanisme de traitement de DelphiSocket (dans Delphi, lorsque vous utilisez un Socket pour envoyer un flux plus grand, le récepteur déclenchera OnRead plusieurs fois. . événement, Delphi garantit uniquement l'intégrité de chaque donnée dans plusieurs événements OnRead, et ne collecte pas les données lui-même et ne les renvoie pas à l'utilisateur, alors ne pensez pas que vous pouvez envoyer le fichier à transférer une fois dans un Socket et Recv une fois dans un autre. Vous devez collecter les données vous-même ou définir le protocole vous-même), nous adoptons donc la méthode du protocole personnalisé. La manière canonique de définir un protocole consiste à utiliser Record End. comme:
TMyFilePRotocol=Enregistrer
sSendType=(ST_QUERY,ST_REFUSE,ST_DATA,ST_ABORT,...);
iLongueur : entier ;
bufSend:Tampon;
Fin;
J'ai essayé cette méthode, mais elle a échoué, et j'ai toujours pensé que ma méthode était correcte, mais la compilation du programme échouait toujours. Je suppose qu'il y avait quelque chose qui n'allait pas avec Delphi :) J'ai donc utilisé une autre méthode dans l'exemple de programme suivant. Il existe deux propriétés, ReceiverText et ReceiverBuf, dans la classe Socket. Dans un événement OnRead, ces deux propriétés ne peuvent être utilisées qu'une seule fois, nous pouvons donc utiliser une variable globale pour enregistrer s'il faut lire Text ou Buf, c'est-à-dire lire. Envoyez un message une fois et relisez-le Buf, cela simule TMyFileProtocol.
Démarrez le programme :
Écrivez le plus simple, principalement utilisé pour expliquer la méthode.
Définir le protocole :
Const
MP_QUERY ='1';
MP_REFUSE ='2';
MP_ACCEPT ='3';
MP_NEXTWILLBEDATA='4';
MP_DATA = '5';
MP_ABORT = '6';
MP_OVER = '7';
MP_CHAT ='8';
Présentation de l'accord :
Tout d'abord, le client envoie MP_QUERY, et après l'avoir reçu, le serveur envoie MP_ACCEPT ou MP_FEFUESE ;
Le client envoie MP_FILEPROPERTY après avoir reçu MP_ACCEPT, et le serveur envoie MP_NEXTWILLBEDATA après l'avoir reçu ;
Le client envoie MP_NEXTWILLBEDATA après l'avoir reçu, et le serveur envoie MP_DATA après l'avoir reçu ;
Le client reçoit MP_DATA et envoie des données, le serveur reçoit des données et envoie MP_NEXTWILLBEDATA ;
Boucle jusqu'à ce que le client envoie MP_OVER ;
MP_CHAT+String peuvent être envoyés entre eux au milieu ;
Programme serveur :
Placez les contrôles suivants : SaveDialog1,btnStartServer,
ss,(TServerSocket)
btnStartServer.OnClick(Expéditeur:TObject);
commencer
ss.Port :=2000 ;
ss.Ouvert ;
fin;
ss.OnClientRead(Expéditeur : TObject;Socket : TCustomWinSocket) ;
var
sTemp:chaîne;
bufRecv:Pointeur;
iRecvLength:entier;
commencer
si bLireTexte alors
commencer
sTemp:=Socket.ReceiveText;
cas sTemp[1] de
MP_QUERY : début
//Rejeter ici
SaveDialog1.FileName:=Copie(sTemp,2,Length(STemp));
si SaveDialog1.Execute alors
commencer
Socket.SendText(MP_ACCEPT);
fsRecv:=TFileStream.Create(SaveDialog1.FileName,fmCreate);
fin
sinon Socket.SendText(MP_REFUSE+'die');
fin;
MP_FILEPROPERTY : début
//Pour envoyer StrToInt(Copy(sTemp,2,Length(sTemp))) fois
//Affichage de la progression du temps. . .
Socket.SendText(MP_NEXTWILLBEDATA);
fin;
MP_NEXTWILLBEDATA : début
Socket.SendText(MP_DATA);
bReadText:=faux;
fin;
MP_END : début
fsRecv.Gratuit
bReadText : = vrai ;
fin;
MP_ABORT : début
fsRecv.Free;
bReadText : = vrai ;
fin;
MP_CHAT : début
//Message de discussion
fin;
fin ;{du cas}
fin
sinon commencer
essayer
GetMem(bufRecv,2000);//2000 doit >iBYTESEND
Socket.ReceiveBuf(bufRecv^,iRecvLength);
fsRecv.WriteBuffer(bufRecv^,iRecvLength);
enfin
FreeMem(bufRecv,2000);
fin ;{d'essayer}
bReadText : = vrai ;
Socket.SendText(MP_NEXTWILLBEDATA);
fin;
fin;
Programme client :
Placez les contrôles suivants : edtipAddress, OpenDialog1, btnConnect, btnSendFile,
cs. (TClientSocket)
btnConnect.OnClick(Expéditeur:TObject);
commencer
cs.Address:=edtIPAddress.Text;
cs.Port :=2000 ;
cs.Connect;
fin;
btnSendFile.OnClick(Expéditeur:TObject);
commencer
si OpenDialog1.Execute alors
Commencer
cs.Socket.SendText(MP_QUERY+OpenDialog1.FileName);//FileSize???