[C con Clase] ayuda con socket

Miguel Olave molavec en gmail.com
Vie Nov 26 14:55:16 CET 2010


podrías mostrar el codigo.

Yo recientemente tuve que trabajar con sockets pero al final el servidor
concurrente lo implemente con hebras.

Por lo que leo de la descripciń de tu problema es que:

- el servidor esta imprimiendo varias veces lo que llego desde el cliente,
por lo que deberías revisar el bucle que recibe los mensajes o como es que
implementaste select

-Es cliente envia repetitivamente el mensaje o texto, Igualmente revisa el
blucle que envia. Alternativamente puedes usar telnet para probar que no sea
el cliente el problema:

     telnet localhost 'port'   <--- y probar

Pillé este código que implementa un servidor con select. Espero que te sirva

/*
NAME:       TCPServer
SYNOPSIS:    TCPServer  [Port_number]
DESCRIPTION:  The program creates a TCP socket in the inet
              listen for connections from TCPClients, accept
              clients into private sockets. It uses select to attend
	      clients' requests as they come.

*/

#include <stdio.h>
#include <errno.h>
#include <sys/time.h>

#include <sys/param.h>
#include <sys/socket.h>
#include <sys/file.h>

#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <netdb.h>


#define MAXHOSTNAME 80
void reusePort(int sock);

main( argc, argv )
int argc;
char *argv[];
{
  int   s, ss;
  struct   sockaddr_in server;
  struct sockaddr_in from;
  int fromlen;
  int length;

  fd_set readfds, readfdsCopy;
  int n,i;
  int sockList[64], lastSock=0;


  /* Construct name of socket to send to. */
  server.sin_family = AF_INET;
  server.sin_addr.s_addr = htonl(INADDR_ANY);
  if (argc == 2)
      server.sin_port = htons(atoi(argv[1]));
  else
      server.sin_port = htons(0);

  s = socket (AF_INET,SOCK_STREAM,0);
  reusePort(s);

  if ( bind( s, (struct sockaddr *)&server, sizeof(server) ) ) {
    close(s);
    perror("binding name to stream socket");
    exit(-1);
  }

  length = sizeof(server);
  if ( getsockname (s, (struct sockaddr *)&server,&length) ) {
    perror("getting socket name");
    exit(0);
  }

  printf("Server Port is: %d\n", ntohs(server.sin_port));

  listen(s,4);
  fromlen = sizeof(from);
  FD_ZERO(&readfdsCopy);
  FD_SET(s,&readfdsCopy);

  for(;;){
    memcpy(&readfds, &readfdsCopy, sizeof(fd_set));
    n = select(FD_SETSIZE, &readfds, (fd_set *) 0, (fd_set *) 0, NULL);
    if (n > 0) {
      if (FD_ISSET(s, &readfds)) {
        printf("Accepting a new connection...\n");
        sockList[lastSock++] = accept(s, (struct sockaddr *)&from, &fromlen);
        FD_SET(sockList[lastSock-1], &readfdsCopy);
      }
      for (i=0; i < lastSock; i++) {
        if (FD_ISSET(sockList[i], &readfds))
          if (EchoServe(sockList[i]) < 0) {
            FD_CLR(sockList[i], &readfdsCopy);
            close (sockList[i]);
            sockList[i] = sockList[--lastSock];
            i--;
            printf("Number of current clients: %d\n", lastSock);
          }
      }
    }
  }
}
int EchoServe(int psd)
{
  char buf[512];
  int rc;

  /*      get data from  clients and send it back */
  for(;;){
    printf("\n...server is waiting...\n");
    if( (rc=read(psd, buf, sizeof(buf))) < 0)
      perror("receiving stream  message");
    if (rc > 0){
      buf[rc]='\0';
      printf("Received: %s\n", buf);
      if (send(psd, buf, rc, 0) <0 )
        perror("sending stream message");
      return(1);
    }
    else {
      printf("Disconnected..\n");
      return(-1);
    }
  }
}
void reusePort(int s)
{
  int one=1;

  if ( setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *) &one,sizeof(one)) == -1 )
  {
    printf("error in setsockopt,SO_REUSEPORT \n");
    exit(-1);
  }
}




2010/11/24 Leonel Florin Selles <leonel06033 en cfg.jovenclub.cu>

> Hola amigos:
>
> Bueno, quiero hacer dos programas que se ejecuten en la misma pc y que se
> comuniquen entre ellos a través de socket tipo UNIX o el sinónimo
> (local)(PF_UNIX) (PF_LOCAL) y a la misma vez estoy utilizando la función
> select, todo me trabaja perfecto, pero cuando el cliente manda datos al
> servidor la función select lo detecta una y otra vez como que el cliente
> esta mandando datos una y otra vez, pero es que el envío de esos datos
> solo los hago una vez, será que estas funciones no trabajan bien con
> sockets de tipo UNIX o LOCAL.
>
> Saludos, alguna sugerencia.
>
>
> _______________________________________________
> Lista de correo Cconclase Cconclase en listas.conclase.net
> http://listas.conclase.net/mailman/listinfo/cconclase_listas.conclase.net
> Bajas: http://listas.conclase.net/index.php?gid=2&mnu=FAQ
>
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://listas.conclase.net/pipermail/cconclase_listas.conclase.net/attachments/20101126/7bab59d8/attachment.html>


Más información sobre la lista de distribución Cconclase