Delphi es poderoso. Escribir software con Delphi puede acortar enormemente el ciclo de desarrollo de software. La idea básica de la transferencia de archivos punto a punto es que un software de servidor y un software de cliente utilizan el mismo puerto. Después de conectarse, el cliente envía una solicitud al servidor, incluido el nombre del archivo, el tamaño, etc. el archivo a transferir Si el servidor Acepta y comienza a transferir archivos. Por supuesto, hay dos modos para la transferencia de archivos, código ASCII y Bin, pero generalmente Bin es suficiente. Según la discusión anterior, originalmente era posible usar los controles NMStrm y NMStrmServ de Delphi4. Sin embargo, lo probé y descubrí que el control NMStrm se puede usar para archivos más pequeños y es muy conveniente, si el archivo es grande (1M. ), se producirá un error. A continuación, usamos TServerSocket y TClientSocket en Delphi para escribir este programa. Debido a la limitación del tamaño del paquete Ethernet y al mecanismo de procesamiento de DelphiSocket (en Delphi, cuando usa un Socket para enviar un Stream más grande, el receptor activará OnRead varias veces). . evento, Delphi solo garantiza la integridad de cada dato en múltiples eventos OnRead, y no recopila los datos en sí ni los devuelve al usuario, así que no crea que puede enviar el archivo para transferirlo una vez en un Socket y recibirlo una vez. en otro. Debe recopilar los datos usted mismo o definir el protocolo usted mismo), por lo que adoptamos el método de protocolo personalizado. La forma canónica de definir un protocolo es utilizar Record End. como:
TMyFilePRotocol=Registro
sSendType=(ST_QUERY,ST_REFUSE,ST_DATA,ST_ABORT,...);
iLongitud:entero;
buffEnviar:Buffer;
Fin;
Probé este método, pero falló, y siempre pensé que mi método era correcto, pero el programa siempre fallaba al compilar. Supongo que había algún problema con Delphi :) Así que utilicé otro método en el siguiente programa de muestra. Hay dos propiedades, RecibirTexto y RecibirBuf, en la clase Socket. En un evento OnRead, estas dos propiedades solo se pueden usar una vez, por lo que podemos usar una variable global para guardar si leer Texto o Buf, es decir, leer. Envíe un mensaje de texto una vez y léalo nuevamente, esto simula TMyFileProtocol.
Inicie el programa:
Escribe el más simple, utilizado principalmente para explicar el método.
Definir protocolo:
constante
MP_QUERY ='1';
MP_REFUSE ='2';
MP_ACCEPT ='3';
MP_NEXTWILLBEDATA='4';
MP_DATA ='5';
MP_ABORT ='6';
MP_OVER ='7';
MP_CHAT ='8';
Introducción del acuerdo:
Primero, el Cliente envía MP_QUERY, y luego de recibirlo, el Servidor envía MP_ACCEPT o MP_FEFUESE;
El Cliente envía MP_FILEPROPERTY después de recibir MP_ACCEPT, y el Servidor envía MP_NEXTWILLBEDATA después de recibirlo;
El Cliente envía MP_NEXTWILLBEDATA después de recibirlo y el Servidor envía MP_DATA después de recibirlo;
El cliente recibe MP_DATA y envía datos, el servidor recibe datos y envía MP_NEXTWILLBEDATA;
Repita hasta que el Cliente envíe MP_OVER;
MP_CHAT+String se puede enviar entre sí en el medio;
Programa de servidor:
Coloque los siguientes controles:SaveDialog1,btnStartServer,
ss,(TServerSocket)
btnStartServer.OnClick(Remitente:TObject);
comenzar
ss.Puerto:=2000;
ss.Abierto;
fin;
ss.OnClientRead(Remitente: TObject;Socket: TCustomWinSocket);
var
sTemp:cadena;
bufRecv:Puntero;
iRecvLength: entero;
comenzar
si bReadText entonces
comenzar
sTemp:=Socket.ReceiveText;
caso sTemp[1] de
MP_QUERY:comenzar
//Rechazar aquí
SaveDialog1.FileName:=Copiar(sTemp,2,Longitud(STemp));
si SaveDialog1.Execute entonces
comenzar
Socket.SendText(MP_ACCEPT);
fsRecv:=TFileStream.Create(SaveDialog1.FileName,fmCreate);
fin
else Socket.SendText(MP_REFUSE+'die');
fin;
MP_FILEPROPERTY:comenzar
//Para enviar StrToInt(Copy(sTemp,2,Length(sTemp))) veces
// Visualización del progreso del tiempo. . .
Socket.SendText(MP_NEXTWILLBEDATA);
fin;
MP_NEXTWILLBEDATA:comenzar
Socket.SendText(MP_DATA);
bReadText:=falso;
fin;
MP_END:comenzar
fsRecv.Free
bReadText:=verdadero;
fin;
MP_ABORT:comenzar
fsRecv.Gratis;
bReadText:=verdadero;
fin;
MP_CHAT:comenzar
//Mensaje de chat
fin;
fin; {de caso}
fin
si no, empezar
intentar
GetMem(bufRecv,2000);//2000 debe >iBYTESEND
Socket.ReceiveBuf(bufRecv^,iRecvLength);
fsRecv.WriteBuffer(bufRecv^,iRecvLength);
finalmente
FreeMem(bufRecv,2000);
fin; {de intentar}
bReadText:=verdadero;
Socket.SendText(MP_NEXTWILLBEDATA);
fin;
fin;
Programa cliente:
Coloque los siguientes controles: editipAddress, OpenDialog1, btnConnect, btnSendFile,
cs.(TClientSocket)
btnConnect.OnClick(Remitente:TObject);
comenzar
cs.Address:=edtIPAddress.Text;
cs.Puerto:=2000;
cs.Conectar;
fin;
btnSendFile.OnClick(Remitente:TObject);
comenzar
si OpenDialog1.Execute entonces
Comenzar
cs.Socket.SendText(MP_QUERY+OpenDialog1.FileName);//FileSize???
fin;
fin;
cs.OnRead(Remitente: TObject;Socket: TCustomWinSocket);
var
sTemp:cadena;
buffEnviar:puntero;
comenzar
sRecv:=Socket.ReceiveText;
Caso sRecv[1] de
MP_REFUSE:ShowMessage('¡Desmayo, ser rechazado!');
MP_ACCEPT:comenzar
fsSend:=TFileStream.Create(OpenDialog1.FileName,fmOpen);
//iBYTEPERSEND es una constante, el tamaño del paquete enviado cada vez.
Socket.SendText(MP_FILEPROPERTY+Trunc(fsSend.Size/iBYTEPERSEND)+1);
fin;
MP_NEXTWILLBEDATA:comenzar
Socket.SendText(MP_NEXTWILLBEDATA);
fin;
MP_DATA:comenzar
intentar
GetMem(bufSend,iBYTEPERSEND+1);
si (fsSend.Position+1+iBYTEPERSEND) < fsSend.Size entonces
comenzar
fsSend.Read(bufSend^,iBYTEPERSEND);
Socket.SendBuf(bufSend^,iBYTEPERSEND);
fsSend.Gratis;
fin // Envío normal, el tamaño es iBYTEPERSEND
si no, empezar
fsSend.Read(bufSend^,fsSend.Size-fsSend.Position-1);
Socket.SendBuf(bufSend^,fsSend.Size-fsSend.Position-1);
end;// La última vez que se envía, envía los datos restantes
finalmente
FreeMem(bufSend,iBYTEPERSEND+1);
fin; {de intentar}
fin;
MP_ABORT:comenzar
//Cancelado :(
fsSend.Gratis;
fin;
fin; {de caso}
fin;
Procedimiento de organización:
Agregue juicio de errores, optimice el programa, combine el Servidor y el Cliente, agregue la visualización del progreso del tiempo restante, haga posible transferir varios archivos a la vez y agregue una función de chat, y se convierte en una buena transferencia de archivos punto a punto. programa.