Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





sockets

Iniciado por cybersersupremo, 16 de Enero de 2008, 01:19:28 PM

« anterior - próximo »

cybersersupremo

hola estoy haciendo un pequeño programa para conectar flash y c++ para luego poder hacer algo mas complejo, todo funciona correctamente, pero no se cmo hacer que todo el rato este conetstando, es decir cuanod me conecto me dice hola, le envio un mensaje desde el cliente y loe scribe en el servidor pero no se como hacer un bucle que cada vez que le envio me conteste! por cierto esto serviria para dos usuarios conectados al vez o el codigo que tnego solo sirve para uno?

#include <stdio.h>
#include <windows.h>

char SendBuff[512],RecvBuff[512];

int main(int argc, char *argv[]){

 WSADATA wsaData;
 SOCKET conn_socket,comm_socket;
 SOCKET comunicacion;
 struct sockaddr_in server;
 struct sockaddr_in client;
 struct hostent *hp;
 int resp,stsize;
 
 //Inicializamos la DLL de sockets
 resp=WSAStartup(MAKEWORD(1,0),&wsaData);
 if(resp){
   printf("Error al inicializar socket\n");
   getchar();return resp;
 }
 
 //Obtenemos la IP que usará nuestro servidor...
 // en este caso localhost indica nuestra propia máquina...
 hp=(struct hostent *)gethostbyname("localhost");

 if(!hp){
   printf("No se ha encontrado servidor...\n");
   getchar();WSACleanup();return WSAGetLastError();
 }

 // Creamos el socket...
 conn_socket=socket(AF_INET,SOCK_STREAM, 0);
 if(conn_socket==INVALID_SOCKET) {
   printf("Error al crear socket\n");
   getchar();WSACleanup();return WSAGetLastError();
 }
 
 memset(&server, 0, sizeof(server)) ;
 memcpy(&server.sin_addr, hp->h_addr, hp->h_length);
 server.sin_family = hp->h_addrtype;
 server.sin_port = htons(6000);

 // Asociamos ip y puerto al socket
 resp=bind(conn_socket, (struct sockaddr *)&server, sizeof(server));
 if(resp==SOCKET_ERROR){
   printf("Error al asociar puerto e ip al socket\n");
   closesocket(conn_socket);WSACleanup();
   getchar();return WSAGetLastError();
 }

 if(listen(conn_socket, 1)==SOCKET_ERROR){
   printf("Error al habilitar conexiones entrantes\n");
   closesocket(conn_socket);WSACleanup();
   getchar();return WSAGetLastError();
 }
             
 // Aceptamos conexiones entrantes
 printf("Esperando conexiones entrantes... \n");
 stsize=sizeof(struct sockaddr);
 comm_socket=accept(conn_socket,(struct sockaddr *)&client,&stsize);
 if(comm_socket==INVALID_SOCKET){
   printf("Error al aceptar conexión entrante\n");
   closesocket(conn_socket);WSACleanup();
   getchar();return WSAGetLastError();
 }
 printf("Conexión entrante desde: %s\n", inet_ntoa(client.sin_addr));
             
 // Como no vamos a aceptar más conexiones cerramos el socket escucha
// closesocket(conn_socket);
             
 strcpy(SendBuff,"Hola Cliente... .P");
 //Enviamos y recibimos datos...
 printf("Enviando Mensaje... \n");
 send (comm_socket, SendBuff, sizeof(SendBuff), 0);
 printf("Datos enviados: %s \n", SendBuff);
 
 printf("Recibiendo Mensaje... \n");
 recv (comm_socket, RecvBuff, sizeof(RecvBuff), 0);
 printf("Datos recibidos: %s \n", RecvBuff);
 
 getchar();            

 // Cerramos el socket de la comunicacion
 closesocket(comm_socket);
 
 // Cerramos liberia winsock
 WSACleanup();
 return (EXIT_SUCCESS);
}

shephiroth

Tu programa segun lo pones es secuencial....es decir, abres el socket y (si todo va bien) envias algo, lees la respuesta y cierras el socket. Prueba a poner algo como esto:


   // Receive until the peer closes the connection
   do {
       iResult = recv(comm_socket, RecvBuff, sizeof(SendBuff), 0);
       if ( iResult > 0 )
           printf("Bytes received: %d\n", iResult);
       else if ( iResult == 0 )
           printf("Connection closed\n");
       else
           printf("recv failed: %d\n", WSAGetLastError());
   } while( iResult > 0 );

cybersersupremo

ahora tengo unas preguntas mas bien de infrasestructura, puedo tener dos conexiones a la vez? o el sitema espera a que termine una para aceptar la otra, o ninguna de las dos cosas!

y la otra pregunta, es por ejemplo si yo tengo 5 usuarios juganod aun juego de coches como hago para que me de los datos de los 5 coches, tendré que guardarlos en algun sitio en le programa c++, no?

y si por ejemplo es un chat que hago, abro un socket cada segundo para saber la gente online y los nuevos mensajeS? saludos y gracias

Martinez

Puedes tener varias conexiones abiertas. Hay varias formas de hacerlo, una forma es dedicar un hilo a aceptar clientes y este cuando llega uno se lo indica al hilo principal. Otra forma es utilizando la funcion select, que espera un tiempo y te indica si hay o no peticiones. Otra es hacer a los sockects no bloqueantes, sino mientras esperar recibir de uno tienes al resto esperando.

Supongamos que la estructura coche_t tiene toda la info de los jugadores. Solo tienes que crear un array: coche_t  pCoches[5]; y cada posicion (0 a 4) indicara un cliente. O puedes hacerlo dinamico coche_t *pCoches; , usa malloc y/o realloc para manejar la memoria. O si usas c++ usa simplente la case vector: vector<coche_t> Coches; que tambien es dinamico y no te tienes que preocupar de la memoria.


Para abrir/cerrar un socket cada  segundo usaria UDP (SOCK_DGRAM) ya que es un protocolo no orientado a conexion. Ten en cuenta que al iniciar una conexion en TCP se mandan 3 mensajes de control. Pero para un chat es mejor utilizar una conexion permanente. Sobre como hacer el servidor de chat hay miles de formas, san google seguro que lo sabe. Pero la mas basica que se me ocurre es que el cliente envie el texto y el servidor se lo envie al resto. Para esto puedes usar el mismo socket o uno para enviar y otro para recibir, como te sea mas comodo. Pero no uses UDP para un chat (los mensajes pueden perderse o llegar desordenados) y manten la conexion (si abres cada segundo para sondear la mitad del tiempo estaras abriendo y cerrando la conexion).






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.