Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Internet (https://www.clubdelphi.com/foros/forumdisplay.php?f=3)
-   -   Tema sockets ¿Por qué no se envían todos los datos? (https://www.clubdelphi.com/foros/showthread.php?t=60295)

noob 26-09-2008 19:59:35

Tema sockets ¿Por qué no se envían todos los datos?
 
Tengo un servidor que todo lo que le llega lo almacena en un archivo de texto:

Código Delphi [-]
procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
var
  Archivo: TextFile;
begin
  System.Assign(Archivo,'archivo.txt');
  System.Rewrite(archivo);
  System.Write(archivo,Socket.ReceiveText);
  System.Close(Archivo);
end;

y tengo un cliente que envía todo el contenido de un archivo de texto al servidor:

Código Delphi [-]
procedure TForm1.Button1Click(Sender: TObject);
var
  caracter: char;
begin
  System.Assign(archivo,'archivo.txt');
  System.Reset(archivo);
  repeat
    System.Read(archivo,caracter);
    ClientSocket1.Socket.SendText(caracter);
  until (EOF(archivo))
  System.Close(archivo);
end;

El caso es que no me llegan todos los datos al servidor, sólo unos pocos y me pregunto por qué pasa esto si en teoría se envían todos y cada unos de los caracteres del fichero original.

Thanks!

droguerman 26-09-2008 22:24:48

Has probado con los componentes Indy, a mi personalmente los que vienen con delphi nunca me han inspirado confianza

Crandel 26-09-2008 23:17:36

Hola noob, yo si utilice bastante los componentes que vienen con delphi y no tuve problemas. Aunque tambien use los indy y son muy buenos tambien.

En el caso de ejemplo especifico me parece que tu problema puede venir por el lado de la longitud de los archivos. Estos componentes no estan diseñados para la transferencia de archivos, solo de texto o pequeños paquetes.

Para el envio de archivos debes utilizar el protocolo FTP. En la coleccion de Indy tienes tanto el cliente como el servidor. Aunque tambien pudes usar los que trae la libreria ICS los tiene que tiene una calidad similar aunque un estilo diferente de uso.

Suerte

noob 27-09-2008 12:18:56

La idea era hacerlo con los sockets que trae Delphi por defecto y sí está claro que el problema viene de que envío archivos muy grandes, pienso que debe de existir algún modo de hacerlo como enviando poco a poco el archivo. A ver si alguien me cuenta algo más. Gracias.

cHackAll 27-09-2008 17:18:53

Bueno, independientemente de la eficacia del componente a utilizar (que al fin y a cabo solo "obedecerá" a la "configuración" del programador), hago énfasis en que el código que utiliza "n00b" :D que envía caracter por caracter el archivo :rolleyes:.

Eso es una practica muy mala, y como yo lo veo es aún mucho peor considerando su algoritmo de recepción de datos, intento explicar el problema;

Button1Click abre el archivo y byte por byte envía su contenido al componente ClientSocket1 el cual envía al socket dicho byte, por su parte el SO utilizando el Nagle algorithm va almacenando estos bytes hasta que el tamaño de envío sea el adecuado, cuando esto ocurre el paquete es enviado (Hablamos de un paquete no del archivo entero).

En el otro extremo de la conexión ServerSocket1ClientRead recive los datos enviados (no es un caracter ni todo el archivo sino un paquete de dimensión X), y crea/sobrescribe el 'archivo.txt' guardando el paquete. Considérese que cada vez que recibe un dato el archivo es pisado!


Para corregir dicho código se puede utilizar un valor X de dimensión mayor a un byte para saber que el archivo debe ser creado, luego enviar los datos sin utilizar el Nagle algorithm (esto configurando el valor TCP_NODELAY del socket), en el otro extremo al recibir un valor mayor a un byte crear el archivo, caso contrario realizar un Append.


Este método es muy lento he ineficaz, lo correcto sería enviar el tamaño del archivo primero, luego el contenido del archivo en bloques de tamaño razonable (~4 Kb).

Saludos

Crandel 27-09-2008 17:24:45

Ese es solo alguno de los problemas que puede tener. A eso se le puede sumar a que los paquetes no lleguen en orden, etc, etc.

Por eso insisto que existe un protocolo especifico para este tipo de aplicaciones. Hacerlo con socket es solo intentar reinventar la rueda.

noob 27-09-2008 18:31:26

Cita:

Empezado por cHackAll (Mensaje 316732)
Considérese que cada vez que recibe un dato el archivo es pisado!

Puse el Assign, el Rewrite y el Close ahí porque pensaba que se enviaba todo en un paquete, ahora lo he modularizado y ya lo hace bien.

Gracias, era por eso al parecer pero como dices he de mejorar el algoritmo para que sea más eficiente.

seoane 29-09-2008 15:04:34

Cita:

Empezado por Crandel (Mensaje 316735)
Ese es solo alguno de los problemas que puede tener. A eso se le puede sumar a que los paquetes no lleguen en orden, etc, etc.

Hasta donde yo se, de que los paquetes lleguen en orden se encarga el protocolo TCP.

Crandel 01-10-2008 16:39:55

Cita:

Empezado por seoane (Mensaje 316989)
Hasta donde yo se, de que los paquetes lleguen en orden se encarga el protocolo TCP.

Si, cuando envias un paquete grande de datos estos se subdividen en paquetes y el protocolo TCP los va a indexar para que se puedan armar en orden.

Pero cuando envias muchos datos como lo hace noob cada paquete de esos no tiene ningun indice que lo relaciones respecto a los otros, son independientes.

En general llegaran en el orden que los envie, pero no nadie lo garantiza.

seoane 01-10-2008 18:03:07

Creo crandel que estas confundido, mientras no se cierre el socket todo lo que envies por el sera recibido en el otro extremo en el mismo orden que lo mandaste, esa es precisamente la diferencia entre un protocolo como TCP y uno como UDP. Otra cosa es que hagas envios abriendo y cerrando sockets, en ese caso no tendrian porque llegar en ningun orden en concreto (tampoco tendria mucho sentido hacerlo asi).

Es mas el protocolo FTP no lo conozco en profundidad, pero el HTTP si, y en este ultimo cuando se envia un fichero (imganes, zip, el mismo texto html) se envia todo junto si ningun otro control en el flujo de datos que el propio TCP que esta por debajo del HTTP. Si como tu dices el protcolo TCP no se encargara de controlar el orden en que llegan los datos a estas alturas la web seria un caos :D

roman 01-10-2008 18:40:01

Cita:

Empezado por seoane (Mensaje 317467)
Creo,mientras,TCP,es,UDP.,envia,abriendo,mismo,porque,tendria,que,protocolo,todo,el,socket,que,que,l legar,que,sockets,otro,dices,en,hagas,orden,en,FTP,como,como,Otra,conozco,extremo,controlar,cosa,TCP ,seria,en,el,HTTP.,estas,otro,en,pero,confundido,un,que,propio,texto,el,ningun,en,diferencia,todo,se,alturas,zip,caos,protocolo,html),envios,por,esta,el,de,no,y,estas,se,ese,crandel,control,un,que,flujo,esa,el,en,por, HTTP,no,fichero,uno,el,este,y,se,que,como,mas,a,lo,el,es,precisamente,el,hacerlo,cerrando,en,envia,de,datos,lo,el,cierre,mandaste,Si,tu,en,cuando,m ucho,el,asi).,en,encargara,protcolo,la,sera,envies,se,caso,mismo,no,ultimo,ningun,(tampoco,llegan,orden,concreto,si,debajo,datos,tendrian, profundidad,y,orden,junto,si,del,sentido,lo,(imganes,la,el,no,TCP,un,recibido,entre,los,web,Es

¿Tú crees? :rolleyes:

:D

// Saludos

seoane 01-10-2008 21:51:22

Cita:

Empezado por roman (Mensaje 317481)
¿Tú crees? :rolleyes:

:eek: :D :D


La franja horaria es GMT +2. Ahora son las 07:40:16.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi