[C con Clase] cerrar cliente y mantener el servidor sockets

nree p_westermani en hotmail.com
Vie Feb 1 12:02:34 CET 2008


Hola, mi programilla de socketts parece que va pero tengo un problema, si cierro la ventana del cliente sin cerrar antes el socket con el servidor el servidor me casca, no se como controlar eso, ademas cuando cierro el socket el cliente no se cierra, todavia me deja escribir dos frases mas (que no llegan al servidor) y despues se cierra. Habia pensado en mandarle un kill, pero tampoco funciona, alguna idea??

os dejo el codigo

cliente.cpp

#include <stdio.h>
#include <stdlib.h>
#include <winsock.h>

#define TAMBUF 1460
#define PORT 1064
#define IP "192.168.1.15"

int main(int argc, char *argv[]) {
	
	WSADATA wsaData;
	int sock,i;
	struct sockaddr_in dir_serv;
	char buf[TAMBUF];

	   if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0)
	   {
	      puts("WSAStartup fallo");
	      return 1;
	   }
	  
	 sock = socket(PF_INET, SOCK_STREAM, 0);
	 if(sock < 0)
	 {
		 perror("no se ha podido crear el socket");
		 exit(1);
	 }else
		 puts("socket creado");
	 
	 dir_serv.sin_family = PF_INET;
	 dir_serv.sin_port = htons(PORT);
	 dir_serv.sin_addr.s_addr =inet_addr(argv[1]);
	 memset(dir_serv.sin_zero, '\0', sizeof dir_serv.sin_zero);
	 
	 if (connect (sock, (struct sockaddr*)&dir_serv, sizeof dir_serv) < 0)
	 {
		 perror("conexion no aceptada");
		 exit(1);
	 }else
		 puts("conectando con el servidor");
	 
	 while (1)
	 {
		 gets(buf);
		 i= send(sock, buf, sizeof(buf), 0);
		 if (i <0)
		 {
			 perror("error en la escritura");
			 exit(1);
		 }
	 }
}

servidor.cpp

#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>

#define TAMBUF 1460
#define PORT 1064	
#define NUM_CON 5


void tramitarChat(struct sockaddr_in *ss,int *pid)
{
	int numbytes;
	char buf[TAMBUF];

	printf("conexion con proceso %i\n",(int)pid);
	while (1)
	{
		numbytes = recv ((int)ss, buf, sizeof(buf), 0);
		if (numbytes < 0)
		{
			perror("error en la transmision de datos");
		}
		if (strcmp(buf,"exit") == 0)
		{
			printf("desconexión de...%i\n", pid);
			close((int)ss);
			exit(0);
		}else
		{
			buf[numbytes]='\0';
			puts(buf);
		}
	}
}



int main(void) {
	
	int sock;
	int sock_dialog;
	struct sockaddr_in dir_ser; 
	struct sockaddr_in dir_cli;
	int numbytes;
	int yes=1, pid;
	socklen_t len;
	char buf[TAMBUF];

	
	
	sock = socket(PF_INET, SOCK_STREAM,0);
	if (sock < 0)
	{
		perror("error de creación de socket");
		exit(1);
	}
	else
	{
		puts("socket creado...");
	}
	
	dir_ser.sin_family = PF_INET;
	dir_ser.sin_addr.s_addr = htonl (INADDR_ANY);
	dir_ser.sin_port = htons (PORT);	
	memset(dir_ser.sin_zero, '\0', sizeof dir_ser.sin_zero);
	
	if (setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1)
	{
		perror("setsockopt");
		exit(1);
	}
	
	if (bind(sock, (struct sockaddr *)&dir_ser,sizeof dir_ser)< 0)
	{
		perror("error en la asignación de dirección");
		exit(1);
	}
	else
		puts("asignando direccion...");
	
	if (listen (sock, NUM_CON) < 0)
	{
		perror("error en la escucha");
		exit(1);
	}else
		puts("socket a la escucha...");
	
	while(1)
	{
		len = sizeof dir_ser;
		sock_dialog = accept(sock, (struct sockaddr *) &dir_cli, &len);
		
		printf("server: conexión de %s\n", inet_ntoa(dir_cli.sin_addr));
		
		if (!fork())
		{
			pid = getpid();
			close(sock);
			tramitarChat((struct sockaddr_in *)sock_dialog,(int *)pid);
		}
		close(sock_dialog);
	}
	return 0;
}


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