PDA

Ver la Versión Completa : obtener datos mediante ServerSocket


martonbarbosa
22-06-2011, 16:27:07
Hola a todos... la verdad estuve leyendo varios codigos sobre delphi en este foro, y a demas de ayudarme bastante con mi proyecto ESTA BUENISIMO!

Acudo a ustedes, porque tengo un problemita que me gustaria resolver.

Estoy haciendo un chat privado que consiste en un Servidor que admite varias conexiones y su cliente respectivo...
El chat funciona de maravilla, el servidor admite todas las conecciones que yo desee y todo. pero me gustaria que mi servidor reciba a demas de la IP del cliente reciba otros datos.

Detallo evento donde el servidor agrega todas las conexiones a un listBox.


procedure TForm1.ServerSocket1ClientConnect(Sender: TObject;
Socket: TCustomWinSocket);
var
x : integer;
begin
TrayIcon1.Tip := 'Servidor de : ' + obtenerUsuarioRed + #13 + #10 + 'Estado: Conectado';
Label1.Caption:= 'Estado Conexion: Conectado'; // en un label, muestra estado de conexion
with listbox1.Items do
begin
Clear; //Primero limpia el listbox, para que cuando un usuario se desconecte se borre.
for X := 0 to serversocket1.Socket.ActiveConnections -1 do
begin
Add(ServerSocket1.Socket.Connections[x].RemoteAddress); // agrega conexiones activas
end
end;
sndplaysound('C:\Windows\Media\chimes.wav', SND_NODEFAULT Or SND_ASYNC); //ejecuta un sonido propio de windows (XP).
end;


Veremos, que a demas de todo, tiene un icono donde se agrega el estado, ejecuta un sonido cuando un cliente se conecta, y en el listbox me agrega la ip de la conexion, y como es multiconexion, me gustaria que ahi me agregue el nombre de la persona que se conecta, yo tengo una funcion que encontre por ahi que obtiene el NOMBRE de usuario de la pc. y me gustaria que en ese listbox aparesca dicho nombre de usuario.

Se les ocurre alguna idea de como mediante los sockets mande diche informacion?

Yo probe asi:
Cuando el cliente se conecta, que mande un mensaje con el comando :

ClientSocket1.Socket.SendText('texto'); //'texto' iria funcion de obtener usuario...


Pero al conectarce otros usuarios, el nombre de usuario no me lo agrega al listbox, sino al memo, que es donde recibo los mensajes...

Ahora, si solo se conecta uno, si el listbox recibe el nombre de usuario...

De paso, les adjunto la funcion para obtener el nombre de usuario de windows por si alguien lo quiere.


function obtenerUsuarioRed : Ansistring;
var
dwI : DWord;
begin
dwI := MAX_PATH;
SetLength (Result, dwI + 1);
if WNetGetUser (Nil, PChar (Result), dwI) = NO_ERROR then
SetLength (Result, StrLen (PChar (Result)))
else
SetLength (Result, 0)
end;


la llamamos asi:


procedure TForm1.FormCreate(Sender: TObject);
begin
//ejemplo, lo ponemos en un label
label1.caption := obtenerUsuarioRed;
end;


alguna idea?


Desde ya muchisimas gracias!

M@rton

Enan0
27-06-2011, 21:39:18
Bueno el tema es mas o menos asi.


Lo que Tendrias que hacer es, en el Eventon Onrecive (creo que es asi) obtener el Texto que queres y luego asignarlo al listbox que queres.

Deverias enviarlo con algun parametro o Clave para que cuando parcees el texto sepas que lo que se envia es el nombre de la PC/usuario.
(espero que entiendas lo que quiero decir)

Es decir:
Para enviar el nombre

//Se Connecta
ClientSocket1.Open;
//envia el Nombre de la Maquina
ClientSocket1.Socket.SendText('#USER#'+obtenerUsuarioRed);


En el servidor:


procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
id:Integer;
Nombre:String;
Begin
//Obtenes el indece de la direccion IP correspondiente
id:=ListBox1.Items.IndexOf(Socket.RemoteAddress);
//Obtenes el nombre enviado
Nombre:=ParcearNombre(Socket.ReceiveText);
//Agreagas el Nombre donde vos quieras
....
.....
End;

// en este caso esta fixeada, pero tambien podrias declarar los Campos que pueden venir.
// para que si viene #MESSAGE# puedas saber que lo que viene es un mensaje, o #IMG# porque se envia un Emoticon, y Leerlo desde un directorio y mostrarlo o lo que se te ocurra.
Function ParcearNombre(S:String):String;
begin
Result:=Copy('#USER#SANTY',POS('#USER#',s) +6,Length(s)-length('#USER#'));
end;




Espero que se entienda. Saludos

Enan0
27-06-2011, 21:49:21
En Verdad Deberia ser:

procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
id:Integer;
Tag,Txt:String;
Begin
//Obtenes el indece de la direccion IP correspondiente
id:=ListBox1.Items.IndexOf(Socket.RemoteAddress);
//Obtenes el nombre enviado
ParcearNombre(Socket.ReceiveText,Tag,Txt);
//Agreagas el Nombre donde vos quieras
//entonces Tenes el TAG y el TEXTO.
//Dependiendo de lo que sea podes ponerlo como MEnsaje o dentro del list box

End;

// en este caso esta fixeada, pero tambien podrias declarar los Campos que pueden venir.
// para que si viene MESSAGE# puedas saber que lo que viene es un mensaje, o IMG#
((porque se envia un Emoticon, y Leerlo desde un directorio y mostrarlo o lo que se te ocurra.
Procedure ParcearNombre(S:String; var Tag,Txt:String);
begin
Tag:=Copy(s,1,POS('#',s) -1);
Delete(s,1,pos('#',s));
txt:=s;
end;


Espero que te sea de ayuda!!

martonbarbosa
28-06-2011, 21:30:09
Antes que nada muchas gracias por tu ayuda!

pero la verdad, es que me parece que no es lo que yo estoy buscando....

Digamos, lo que quiero, es que cuando un usuario se conecte, en mi servidor (en el listbox) me aparezca el nombre de usuario.

En ese caso, tendria que definir algo parecido en el evento OnClientConnect, no en el evento OnRead, ya que en eso evento esta definido la accion de recibir mensajes...

Se entiende?

Porque cuando se conecta un usuario, se genera un evento, que lo recibo en el evento OnClientConnect, ahi es donde deberia de hacer algo asi como dices vos.
Lo intente y no hubo caso...

Quise poner una imagen pero no me dejo :/

De utima si te parece nos ponemos en contacto por msn a ver si me das una manito :D

Desde ya muchisimas gracias!

Salu2

M@rton

Enan0
29-06-2011, 16:30:21
Bueno te comento te dejo un ejemplo de lo que te decia aca en el ftp del foro
http://www.terawiki.clubdelphi.com/archivos/Delphi/Ejemplos/SampleSocket.zip

Lo que hice es un Cliente y servidor en la misma unidad porque es solo para demostrarte como hacer lo que te decia con el Nombre que queres enviar.

Cambie tu ListBox por un LitView en modo vsReport, con 2 columnas una para la IP (oculta) y otra donde Pones el Nombre de Usuario. (o de red lo que Quieras).

En este Caso yo utilizo enviar un nombre que se pone en un Edit.l y al hacer click en connect, Se conecta al servidor, y al establecer la conexion le envia ese nombre.

el servidor Recibe la conexion y Luego recibe el nombre. Busca en el ListView la IP devuelve el ID y pone el nombre que se envio.

Por ultimo Seleccionando el nombre, Podes hacer click en el boton "Snd MSG Client" y le enviara al Cliente un mensaje prefijado que sera mostrado en el MEMO que tiene el ejemplo.

Para enviar el Mensaje, se busca por el Item seleccionado la IP, se verifica que sea una IP activa y luego le envia el mensaje.

es algo muy basico pero creo que puede darte una idea.

saludos.

PD: si tenes ganas te recomiendo que uses Los componentes de INDY ya que son un poco mas estables y potentes.

en caso de que quieras enviar algun archivo o algo similar decime que te comento como hacerlo ( esto lo he hecho con los componentes INDY.)

saludos y Espero haberte ayudado..

PD2: Use delphi 5