Sockets erreur

cs_kalif Messages postés 362 Date d'inscription mardi 18 décembre 2001 Statut Membre Dernière intervention 24 août 2012 - 17 févr. 2006 à 10:47
cs_kalif Messages postés 362 Date d'inscription mardi 18 décembre 2001 Statut Membre Dernière intervention 24 août 2012 - 18 févr. 2006 à 21:07
bonjour a tous

avec un TServerSocket,
propriété:
active = true
ServerType = stNonBlocking
Port = 1513

je me connecte avec un client et il es connecté mais quand j'essaye d'enfoyer soit un fichier ou soit un simple mot comme ceci ca ne voncitonne pas

sck.Socket.SendText('salu');

> erreur:
a provoqué une classe d'exeption ESocketError avec le message 'Erreur sockets Winows: Une requete d'envoi ou de réception de données n'a pas été autorisée car le socket n'est pas connecté et (lors de l'envoi sur un socket datagramme en utilisant un appel sendto) aucune adresse n'a été fournie (10057), avec l'API 'send". Processus stopé ....

D'avance merci
A voir également:

12 réponses

Utilisateur anonyme
17 févr. 2006 à 15:38
Salut

C'est normal : ton serveur peut etre connecté à différents clients il faut donc le préciser sinon ton serveur il ne sait pas à qui envoyer le message :

Voila la procedure

Procedure TForm1.mot ;
begin
ServerSocket1.Socket.Connections[0].SendText('salut');
end;

A+ et clique sur accepter si la réponse te convient
0
cs_kalif Messages postés 362 Date d'inscription mardi 18 décembre 2001 Statut Membre Dernière intervention 24 août 2012
17 févr. 2006 à 21:45
merci tu as vu juste mais pourquoi es ce que dans le projet qu'un amis m'avais envoyer il ne devais pas presicer la connexion 0 ? y'a t il une procedure qui fait que le serveur ne peut avoir qu'une seule connexion ?
0
cs_kalif Messages postés 362 Date d'inscription mardi 18 décembre 2001 Statut Membre Dernière intervention 24 août 2012
17 févr. 2006 à 21:54
ha nan mille excuse c'est une erreur de ma parre merci pour ta réponse ca fonctionne (ps impossible de valider ta reponse sous firefox)
0
Utilisateur anonyme
17 févr. 2006 à 21:54
Tu es sur qu'il utilisait les composants TSocket et pas plutot les composants Indy ??

Sache que l'erreur que tu as fais un CLASSIQUe et moi aussi j'ai fais cette erreur au début.

N'oublies pas de cliquer sur ACCEPTER (en bas à gauche sur le message que j'ai posté) comme ca si une autre personne rencontre le probleme elle sera qu'une solution a été trouvé.

Merci de le faire
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_kalif Messages postés 362 Date d'inscription mardi 18 décembre 2001 Statut Membre Dernière intervention 24 août 2012
17 févr. 2006 à 23:07
ok merci mai j'ai une dernière question:

dans un projet client/serveur j'envoi un fichier jpeg
donc au niveau de l'envoi ca fonctionne bien et a la reception je met ca:

p:=sck.Socket.ReceiveBuf(tab,sck.Socket.ReceiveLength);
showmessage(inttostr(p));
blockwrite(file1,tab,p,w);
assignfile(file1,'C:\b.jpg');
rewrite(file1);

//variable// p,w:longint // tab:array[1..100000] of byte; //file1:file of byte;
ca plante... tu sais m'aider ?
0
flor003 Messages postés 118 Date d'inscription dimanche 28 septembre 2003 Statut Membre Dernière intervention 19 juin 2007
18 févr. 2006 à 00:34
array[1..100000] of byte

un peu lourd non ?
0
cs_kalif Messages postés 362 Date d'inscription mardi 18 décembre 2001 Statut Membre Dernière intervention 24 août 2012
18 févr. 2006 à 11:01
heuu oui et non j'ai essayer moin tjrs la meme erreur
0
Utilisateur anonyme
18 févr. 2006 à 16:30
IL faut mettre bcp moins que 100000] parce que la c'est sur que cela ne vas jamais marché. Si tu veux que l'on t'aide il faut etre bcp plus précis sur ta source et ce d'une facon générale : tu dois mettre toute ta source. Qui dit que sur tu l'envoye bien sur le serveur et que tu es bien sur la procedure Onread.

Maintenant sache que les TSockets sont bcp plus lourd à utiliser que les composants Indy pour le transfert de fichier. En effet pour les composants indy on peut utiliser les streams comme TFilestream et dans ton cas de figure un Tmemorystream fonctionne tres bien et est suffisant. Autrement dit tu n'es pas obligé de mettre ton JPEG dans un fichier coté client puis de le transferer comme un fichier sur le serveur.

A+
0
cs_kalif Messages postés 362 Date d'inscription mardi 18 décembre 2001 Statut Membre Dernière intervention 24 août 2012
18 févr. 2006 à 20:08
ok voici plus de précision:
du coté serveur une fois que la connexion est établie on envoi le fichiers vers le client qui le demande comme ca:

/// déclaration de variable dans les deux projet (client et serveur)
file1:file of byte;
i,z,r:longint;
tab:array[1..100000] of byte;
//////////////////


///////voici le serveur
assignfile(file1,'C:\a.jpg');
reset(file1);
z:=filesize(file1);

//repetition dans un timer
blockread(file1,tab,sizeof(tab),r);
sck.Socket.Connections[0].SendBuf(tab,r);
i:=i+r;
if i>=z then
begin
sck.Close;
closefile(file1);
timer2.enabled:=false
end;
// fin


du coté client une fois que j'ai demander le fichier en question, le serveur me renvoi et j'aimerai savoir comment le réceptionner, j'ai utiliser cette methode mais ca plante

//voila le client
p:=sck.Socket.ReceiveBuf(tab,sck.Socket.ReceiveLength);
blockwrite(file1,tab,p,w);
assignfile(file1,'C:\b.jpg');
rewrite(file1);
0
Utilisateur anonyme
18 févr. 2006 à 20:53
Plusieurs choses :

*Deja est tu sur que l'on peut faire un transfert client----> serveur ?? Regarde bien les tutos donc celui de Nono 40 : on fait tjs le transfere du client vers le serveur. Il en va de même avec les composants Indy.

*Deuxièmement chose : si tu fais une boucle sur le serveur il faut en faire de meme avec le client. Ca semble logique non ??

*Troisièmement : Ne pas utiliser de timer mais utiliser "CASE". En effet c'est dangereux avec un timer : comment est tu sur que le temps de répétition est ni trop long ni trop court.

Je me répète : pour faire des transferts les composants indy sont plus facile. Il te suffit d'utiliser un Antifreeze pour ne pas avoir le coté négatif des serveurs bloquants.

A mon gout personnel, les composants TSockets sont dépassés. En effet utiliser cette technique est un peu dépassé quand on connait les streams. Je vais te prendre un exemple tres simple (voir une source que j'ai posté). Si tu as un fichier WAV en ressource. Avec les composants TSockets tu est obligé d'extraire ta ressource dans un fichier puis de le transferer. Avec les composants Indy tu mets ton fichier ressource en mémoire par un TMemoryStream et tu le transfères sans meme avoir créer ton fichier.

Pour conclure, je n'ai jamais pu implanter proprement (au sens du codage) un transfert de fichier en utilisant un Tsocket qui faisait autre chose. Avec les composants Indy, j'ai pu le faire. Si tu veux utilser TSockets regarde la source de Nono40.

A+
0
Utilisateur anonyme
18 févr. 2006 à 21:02
Je vais te citer différents postesde Developpez.com :

"Les composants TClientSocket et TServerSocket ne sont plus installés par défaut avec Delphi7. Mais ils sont encore fournis. Il suffit d'installer le paquet /bin/dclsockets70.bpl via le menu Composants->Installer des paquets...

Il faut éviter de s'en servir pour de nouvelles applications, ils sont remplacés par les composants TCPClient/TTcpServer ou les composants Indy TIDTcpClient/TIDTcpServer. Cette méthode n'est donnée ici que pour assurer la compatibilité des applications Delphi5/Delphi6 avec Delphi7."

---------------------------------------------------------------
Transferer un fichier avec Indy

function TForm1.SendFile(const AFileName: string;
ATcpClient: TIdTCPClient) : Boolean;
var
Fs : TFileStream;
begin
Result := False;
ATcpClient.Connect(); //Connecte. Les propriétés Host et Port doivent être remplies.
try
Fs := TFileStream.Create(AFileName,fmOpenRead,fmShareDenyWrite); //Créer le flux
try
ATcpClient.WriteLn(Format('TRANS %s',[ExtractFileName(AFileName)])); //demander transfert
try
ATcpClient.WriteInteger(Fs.Size); //Ecrire la taille
ATcpClient.WriteStream(Fs); //Ecrit le flux
except
MessageDlg('Erreur pendant l''envoi du fichier.', mtError, [mbOK], 0);
end;
finally
FreeAndNil(Fs); //Libérer le flux
Result := ATcpClient.ReadLn()='OK'; //OK uniquement si le serveur a renvoyé "OK"
end;
finally
ATcpClient.Disconnect; //Déconnecter à la fin.
end;
end;

Code du serveur :

procedure TForm1.IdTCPServerExecute(AThread: TIdPeerThread);
var
Line, FileName : String;
i, FileSize : integer;
Fs : TFileStream;
begin
with AThread.Connection do
try
Line := ReadLn(); //Attends une commande de la forme TRANS suivi du nom de fichier
i := Pos(' ',Line);
if (i>0) and (LowerCase(Copy(Line,1,Pred(i)))='trans') then
begin
FileName := IncludeTrailingPathDelimiter(ExtractFilePath(Application.ExeName))
+ Copy(Line,Succ(i),Length(Line)); //Copier nom de fichier
Fs := TFileStream.Create(FileName,fmCreate); //Créer le flux
try
try
FileSize := ReadInteger(); //Lire la taille
ReadStream(Fs,FileSize,False); //Lire le flux
WriteLn('OK'); //Signaler succès
except
WriteLn('ERR'); //Signaler une erreur
end;
finally
FreeAndNil(Fs); //Libérer le flux dans tous les cas
end;
end
else
WriteLn('ERR'); //Commande incomprise
finally
Disconnect; //A la fin, on déconnecte
end;
end;

Exemple d'exploitation :

procedure TForm1.Button1Click(Sender: TObject);
begin
IdTCPClient.Host := 'localhost'; //Hôte
IdTCPClient.Port := 1985; //Le serveur doit aussi écouter sur le port 1985
if SendFile('c:\setup.exe',IdTCPClient) then
MessageDlg('Ok !', mtInformation, [mbOK], 0)
else
MessageDlg('Erreur...', mtInformation, [mbOK], 0)
end;

----------------------------------------------------------------------

Unit Unit1;

Interface

Uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ScktComp, ExtCtrls;

Type
TForm1 = Class(TForm)
Client: TClientSocket;
Serveur: TServerSocket;
GroupBox1: TGroupBox;
btnOpen: TButton;
btnClose: TButton;
MemoServeur: TMemo;
GroupBox2: TGroupBox;
btnEnvoyer: TButton;
btnStop: TButton;
Edit1: TEdit;
Ouvrir: TOpenDialog;
MemoClient: TMemo;
RetardDebut: TTimer;
Procedure btnOpenClick(Sender: TObject);
Procedure btnCloseClick(Sender: TObject);
Procedure ServeurClientConnect(Sender: TObject;
Socket: TCustomWinSocket);
Procedure ServeurClientDisconnect(Sender: TObject;
Socket: TCustomWinSocket);
Procedure ServeurClientError(Sender: TObject; Socket: TCustomWinSocket;
ErrorEvent: TErrorEvent; Var ErrorCode: Integer);
Procedure ServeurClientRead(Sender: TObject; Socket: TCustomWinSocket);
Procedure ClientConnect(Sender: TObject; Socket: TCustomWinSocket);
Procedure ClientDisconnect(Sender: TObject; Socket: TCustomWinSocket);
Procedure ClientError(Sender: TObject; Socket: TCustomWinSocket;
ErrorEvent: TErrorEvent; Var ErrorCode: Integer);
Procedure btnEnvoyerClick(Sender: TObject);
Procedure ClientRead(Sender: TObject; Socket: TCustomWinSocket);
Procedure btnStopClick(Sender: TObject);
Procedure RetardDebutTimer(Sender: TObject);
Private
{ Déclarations privées }
Public
{ Déclarations publiques }
End;

Var
Form1: TForm1;


Implementation

{$R *.dfm}

//**************************************************************************************
//
// Principe :
// le fichier envoyé en coupé en tranches de taille identiques et e transmises au serveur
// dans l'ordre du fichier.
//
// - Le client se connecte au serveur.
// - Si la connection est OK alors il envoie un trame du type ci-dessous avec ttType=1
// signalant qu'il s'agit du nom du fichier. ttNomFichier est alors le nom du fichier
// transféré.
// - Si le serveur accepte la demande, alors le fichier est envoyé par morceau avec le même
// type de trame. ttType = 2 pour signaler qu'il s'agit un morceau du fichier. ttDebut
// donne l'adresse du bloc dans le fichier et ttLong la taille du bloc.
// - Le client se deconnecte, ce qui ferme le fichier sur le serveur.
//
//**************************************************************************************



//**************************************************************************************
// Procédure d'affichage en clair des erreurs socket
// merci à djtexas
Function MessageErreurSocket( ErrorEvent: TErrorEvent; Var ErrorCode: Integer):String;
Var
ErrorMsg: String;
Begin
// définition du message d'erreur en fonction du code d'erreur
Case ErrorCode Of
10004 : ErrorMsg := 'Interrupted Function call.';
10013 : ErrorMsg := 'Permission Refusée.';
10014 : ErrorMsg := 'Mauvaise adresse.';
10022 : ErrorMsg := 'Arguments Invalides.';
10024 : ErrorMsg := 'Trop de fichiers ouverts.';
10035 : ErrorMsg := 'Resource temporarily unavailable.';
10036 : ErrorMsg := 'Operation en cours.';
10037 : ErrorMsg := 'Operation déjà en cours.';
10038 : ErrorMsg := 'Socket operation On non-socket.';
10039 : ErrorMsg := 'Destination address required.';
10040 : ErrorMsg := 'Message trop long.';
10041 : ErrorMsg := 'Protocol wrong Type For socket.';
10042 : ErrorMsg := 'Bad protocol option.';
10043 : ErrorMsg := 'Protocol Not supported.';
10044 : ErrorMsg := 'Socket Type Not supported.';
10045 : ErrorMsg := 'Operation Not supported.';
10046 : ErrorMsg := 'Protocol family Not supported.';
10047 : ErrorMsg := 'Address family Not supported by protocol family.';
10048 : ErrorMsg := 'Address already In use.';
10049 : ErrorMsg := 'Cannot assign requested address.';
10050 : ErrorMsg := 'Network Is down.';
10051 : ErrorMsg := 'Network Is unreachable.';
10052 : ErrorMsg := 'Network dropped connection On reset.';
10053 : ErrorMsg := 'Software caused connection abort.';
10054 : ErrorMsg := 'Connection reset by peer.';
10055 : ErrorMsg := 'No buffer space available.';
10056 : ErrorMsg := 'Socket Is already connected.';
10057 : ErrorMsg := 'Socket Is Not connected.';
10058 : ErrorMsg := 'Cannot send after socket shutdown.';
10060 : ErrorMsg := 'Connection timed Out.';
10061 : ErrorMsg := 'Connection refused.';
10064 : ErrorMsg := 'Host Is down.';
10065 : ErrorMsg := 'No route To host.';
10067 : ErrorMsg := 'Too many processes.';
10091 : ErrorMsg := 'Network subsystem Is unavailable.';
10092 : ErrorMsg := 'WINSOCK.DLL version Out Of range.';
10093 : ErrorMsg := 'Successful WSAStartup Not yet performed.';
10094 : ErrorMsg := 'Graceful shutdown In progress.';
11001 : ErrorMsg := 'Host Not found.';
11002 : ErrorMsg := 'Non-authoritative host Not found.';
11003 : ErrorMsg := 'This Is a non-recoverable error.';
11004 : ErrorMsg := 'Valid name, no data Record Of requested Type.';
Else
// erreur inconnue
ErrorMsg := 'Unknown socket error.';
End;
// mise en forme de la signification de l'erreur
ErrorMsg := 'Socket Error n°' + IntToStr(ErrorCode) + ' : ' + ErrorMsg;
// l'erreur est traitée
ErrorCode := 0;
// définition du type d'erreur
Case ErrorEvent Of
eeSend : ErrorMsg := 'Writing ' + ErrorMsg;
eeReceive : ErrorMsg := 'Reading ' + ErrorMsg;
eeConnect : ErrorMsg := 'Connecting ' + ErrorMsg;
eeDisconnect : ErrorMsg := 'Disconnecting ' + ErrorMsg;
eeAccept : ErrorMsg := 'Accepting ' + ErrorMsg;
Else
// erreur inconnue
ErrorMsg := 'Unknown ' + ErrorMsg;
End;
Result:=ErrorMsg;
End;
//
//**************************************************************************************



//**************************************************************************************
// Structure de la trame utilisée pour les échanges
//
Const
TailleBloc = 256;
Type
TIPTrame=Packed Record
Case ttType:Integer Of // ttType précise le type de la trame
// =1 quand c'est un nom de fichier
// =2 quand c'est un morceau du fichier
1:(
ttNomFichier:String[255]; // Nom du fichier
);
2:( ttDebut : Integer; // Adresse de début des données dans le fichier
ttLong : Integer; // Longueur des données envoyées
ttDatas : Array[0..TailleBloc-1] Of Byte ) // Données envoyées
End;
//
//**************************************************************************************



//**************************************************************************************
// SERVEUR
// Cette partie ne concerne que le serveur
Var
ServeurEnReception : Boolean False; //True quand une réception est en cours
ServeurAdresseClient : String = ''; // Adresse du client connecté
ServeurFichier : File; // Fichier utilisé pour la sauvegarde des morceaux


Procedure TForm1.btnOpenClick(Sender: TObject);
Begin
// Bouton de mise en écoute du serveur, c'est tout simple
Serveur.Open;
MemoServeur.Lines.Add('Serveur en écoute');
End;

Procedure TForm1.btnCloseClick(Sender: TObject);
Begin
// Bouton de fermeture du serveur, c'est aussi tout simple
If ServeurEnReception
And (MessageDlg('Un transfert est en cours, fermer le serveur ?',mtConfirmation,[mbYes,mbNo],0)=mrYes)
Then Begin
Serveur.Close;
MemoServeur.Lines.Add('Serveur desactivé');
End;
End;

//
// évènements du socket serveur
//
Procedure TForm1.ServeurClientConnect(Sender: TObject;
Socket: TCustomWinSocket);
Begin
// C'est juste pour signaler
MemoServeur.Lines.Add('OnConnect:'+Socket.RemoteAddress);
End;

Procedure TForm1.ServeurClientDisconnect(Sender: TObject;
Socket: TCustomWinSocket);
Begin
MemoServeur.Lines.Add('OnDisconnect:'+Socket.RemoteAddress);
// Le client se deconnecte => ou ferme le fichier en cours si besoin
If ServeurEnReception
Then Begin
CloseFile(ServeurFichier);
ServeurEnReception:=False;
End;
End;

Procedure TForm1.ServeurClientError(Sender: TObject;
Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
Var ErrorCode: Integer);
Begin
// On ne fait que signaler l'erreur
MemoServeur.Lines.Add('OnClientError:'+Socket.RemoteAddress+#13+MessageErreurSocket(ErrorEvent,ErrorCode));
End;

Procedure TForm1.ServeurClientRead(Sender: TObject;
Socket: TCustomWinSocket);
Var Buffer:TIPTrame;
Erreur:Integer;
Recus :Integer;
Begin
// C'est ici la partie principale du serveur
// Cette procédure est appelée à chaque écriture d'un client

Erreur :=0;
Recus :=Socket.ReceiveLength; // Longueur reçue ( en octets )
MemoServeur.Lines.Add('OnRead'+Socket.RemoteAddress+' reçus '+IntToStr(Recus));

If Recus<= SizeOf(Buffer) // On vérifie que la longueur reçue tient dans la trame
// sinon attention au plantage !!!
Then With Buffer Do Begin
// Lecture de la trame reçue
Socket.ReceiveBuf(Buffer,Recus);

// En fonction du type de la trame on effectue les traitements
Case ttType Of
1:Begin
// C'est une nouvelle demande, on vérifie le nom du fichier
// La longueur de la trame doit être au minimumu de
// 4 ( taille de ttType ) + 1 ( longueur de la chaine ttNomFichier ) + Length(ttNomFichier)
If (Recus>=5)And(Recus>=(5+Length(ttNomFichier)))
Then Begin
// La longueur est bonne, on accepte la demande
MemoServeur.Lines.Add(ttNomFichier);

// On ferme le fichier précédent au cas ou
If ServeurEnReception Then CloseFile(ServeurFichier);

// On ouvre le fichier de réception en écriture
AssignFile(ServeurFichier,ExtractFilePath(ParamStr(0))+ttNomFichier);
Try
Rewrite(ServeurFichier,1);
ServeurEnReception:=True;
Erreur:=0;
Except
Erreur:=5; // Erreur de création du fichier
End;
End
Else Erreur:=2; // La longueur reçue est trop courte
End;

2:Begin
// On reçoit un morceau de fichier
// La longueur de la trame doit être au minimumu de
// 4 ( taille de ttType ) + 4 ( taille de ttDebut ) + 4 ( taille de ttLong )
// + ttLong ( nombre de données envoyées )
If (Recus>=12)And(Recus>=(12+ttLong))
Then Begin
// Le morceau n'est accepté que si une demande est en cours
If ServeurEnReception
Then Begin
// Le morceau n'est accepté que si le début du fichier à déjà été reçu
If (ttDebut>=0)And(ttDebut<=FileSize(ServeurFichier))
Then Begin
Try
// Si tout est bon on écrit le morceau dans le fichier
Seek(ServeurFichier,ttDebut);
BlockWrite(ServeurFichier,ttDatas,ttLong);
Erreur:=0; // C'est bon
Except
Erreur:=6; // Erreur d'écriture du fichier
End;
End
Else Erreur:=4; // La position 'début' n'est pas correcte
End
Else Erreur:=3; // On n'a pas reçue de demande
End
Else Erreur:=2; // La longueur reçue est trop courte
End;

End;// fin du case
End
Else Erreur:=1; // La longueur reçue est trop grande

// Dans tout les cas on envoie le code d'erreur au client
Socket.SendBuf(Erreur,4);
MemoServeur.Lines.Add(' Code de retour :'+IntToStr(Erreur));
End;
// fin de la partie serveur
//**************************************************************************************



//**************************************************************************************
// CLIENT
// Cette partie ne concerne que le client
Var
ClientFichier : File; // Fichier en cours d'envoi
ClientTrame : TIPTrame; // Copie de la dernière trame envoyée

Procedure TForm1.btnEnvoyerClick(Sender: TObject);
Begin
// Bouton envoyer, c'est le début
// On demande bien sur en premier le nom de fichier à transférer
If Not Ouvrir.Execute Then Exit;
AssignFile(ClientFichier,Ouvrir.FileName);

// On ouvre le fichier en lecture
Reset(ClientFichier,1);

// On essaye de se connecter au serveur
Client.Address:=Edit1.Text;
Client.Open;
End;

Procedure TForm1.ClientConnect(Sender: TObject; Socket: TCustomWinSocket);
Begin
// La connection est réussie
MemoClient.Lines.Add('OnConnect:'+Socket.RemoteAddress);

// On demande alors l'envoi de la trame d'entête
ClientTrame.ttType:=1;
ClientTrame.ttNomFichier:=ExtractFileName(Ouvrir.FileName);

// La demande est différée par un petit timer car il est interdit
// d'écrire dans un OnConnect
btnEnvoyer.Enabled:=False;
RetardDebut.Enabled:=True;
End;

Procedure TForm1.RetardDebutTimer(Sender: TObject);
Begin
// Cette demande n'est faite qu'une fois par fichier
RetardDebut.Enabled:=False;

// On envoie au serveur la trame avec le nom du fichier
Client.Socket.SendBuf(ClientTrame,4+Length(ClientTrame.ttNomFichier)+1);
MemoClient.Lines.add('Envoi de l''entête');
End;

Procedure EnvoiBlocEnCours;
Begin
With ClientTrame Do
Begin
// Procédure d'envoi d'un morceau de fichier
// est appelée par ClientRead

// C'est une trame de type morceau de fichier
ttType:=2;

// Lecture dans le fichier
Seek(ClientFichier,ttDebut);
BlockRead(ClientFichier,ttDatas,TailleBloc,ttLong);

// Envoi du morceau
// La longueur envoyée est
// 4 ( taille de ttType ) + 4 ( taille de ttDebut ) + 4 ( taille de ttLong )
// + ttLong ( nombre de données envoyé )
Form1.Client.Socket.SendBuf(ClientTrame,ttLong+12);
Form1.MemoClient.Lines.add('Envoi du morceau '+IntToStr(ttDebut)+'['+IntToStr(ttLong)+']');
End;
End;

Procedure TForm1.ClientRead(Sender: TObject; Socket: TCustomWinSocket);
Var CodeRetour:Integer;
Begin
With ClientTrame Do
Begin
// On reçoit le code d'erreur du serveur, on le traite suivant les cas
MemoClient.Lines.Add('OnRead:'+Socket.RemoteAddress);
Socket.ReceiveBuf(CodeRetour,4);

Case ttType Of
1:Begin
// La dernière demande était un nom de fichier
// On teste le code de retour
If CodeRetour=0
Then Begin
// Par d'erreur, l'envoi réel peut donc commencer
ttDebut:=0;
EnvoiBlocEnCours;
End
Else Begin
// Le serveur refuse le fichier demandé => on arrète
MemoClient.Lines.Add('Erreur '+IntToStr(CodeRetour));
Client.Close;
End;
End;

2:Begin
// La dernière demande était un morceau de fichier
// On teste le code de retour
If CodeRetour=0
Then Begin
// Pas d'erreur on avance dans le fichier de la longueur envoyée précédemment
Inc(ttDebut,ttLong);
If ttDebut>=FileSize(ClientFichier)
Then Client.Close // C'est la fin du fichier, on ferme la connection
Else EnvoiBlocEnCours; // ce n'est pas la fin, on envoie le morceau
End
Else Begin
// Une erreur à eut lieu, on envoie le même morceau
MemoClient.Lines.Add('Erreur '+IntToStr(CodeRetour));
EnvoiBlocEnCours;
End;
End;

Else
// Normalement on ne doit pas passer ici.
// au cas ou, on ferme la connection
Client.Close;
End;
End;
End;

Procedure TForm1.ClientDisconnect(Sender: TObject;
Socket: TCustomWinSocket);
Begin
// à la déconnection on ferme le fichier est cours de lecture
MemoClient.Lines.Add('OnDisonnect:'+Socket.RemoteAddress);
btnEnvoyer.Enabled:=True;
CloseFile(ClientFichier);
End;

Procedure TForm1.ClientError(Sender: TObject; Socket: TCustomWinSocket;
ErrorEvent: TErrorEvent; Var ErrorCode: Integer);
Begin
// On ne fait que signaler l'erreur
MemoServeur.Lines.Add('OnClientError:'+Socket.RemoteAddress+#13+MessageErreurSocket(ErrorEvent,ErrorCode));
End;

Procedure TForm1.btnStopClick(Sender: TObject);
Begin
// Arrêt du transfert en cours
RetardDebut.Enabled:=False;
Client.Close;
End;
// fin de la partie client
//**************************************************************************************

End.



///////////////////////////////////

Voila deux sources (Indy et Socket) qui font la meme chose : a ton avis c'est laquelle la source la plus simple ???

A+
0
cs_kalif Messages postés 362 Date d'inscription mardi 18 décembre 2001 Statut Membre Dernière intervention 24 août 2012
18 févr. 2006 à 21:07
ok merci bcp je vais jetter un coup d'oeil ce soir, je sais déjà que indy est plus simple ;)
0
Rejoignez-nous