//funciones para la mac int main(int argv, char** argc){ int socket_host; struct sockaddr_in client_addr; struct sockaddr_in my_addr; struct timeval tv; /* Para el timeout del accept */ socklen_t size_addr = 0; int socket_client; fd_set rfds; /* Conjunto de descriptores a vigilar */ int childcount=0; int exitcode; int childpid; int pidstatus; int activated=1; int loop=0; socket_host = socket(AF_INET, SOCK_STREAM, 0); if(socket_host == -1) error(1, "No puedo inicializar el socket"); my_addr.sin_family = AF_INET ; my_addr.sin_port = htons(PORT); my_addr.sin_addr.s_addr = INADDR_ANY ; if( bind( socket_host, (struct sockaddr*)&my_addr, sizeof(my_addr)) == -1 ) error(2, "El puerto está en uso"); /* Error al hacer el bind() */ if(listen( socket_host, 10) == -1 ) error(3, "No puedo escuchar en el puerto especificado"); size_addr = sizeof(struct sockaddr_in); while(activated) { reloj(loop); /* select() se carga el valor de rfds */ FD_ZERO(&rfds); FD_SET(socket_host, &rfds); /* select() se carga el valor de tv */ tv.tv_sec = 0; tv.tv_usec = 500000; /* Tiempo de espera */ if (select(socket_host+1, &rfds, NULL, NULL, &tv)) { if((socket_client = accept( socket_host, (struct sockaddr*)&client_addr, &size_addr))!= -1) { loop=-1; /* Para reiniciar el mensaje de Esperando conexión... */ printf("\nSe ha conectado %s por su puerto %d\n", inet_ntoa(client_addr.sin_addr), client_addr.sin_port); switch ( childpid=fork() ) { case -1: /* Error */ error(4, "No se puede crear el proceso hijo"); break; case 0: /* Somos proceso hijo */ if (childcount<MAX_CHILDS) exitcode=AtiendeCliente(socket_client, client_addr); else exitcode=DemasiadosClientes(socket_client, client_addr); exit(exitcode); /* Código de salida */ default: /* Somos proceso padre */ childcount++; /* Acabamos de tener un hijo */ close(socket_client); /* Nuestro hijo se las apaña con el cliente que entró, para nosotros ya no existe. */ break; } } else fprintf(stderr, "ERROR AL ACEPTAR LA CONEXIÓN\n"); } /* Miramos si se ha cerrado algún hijo últimamente */ childpid=waitpid(0, &pidstatus, WNOHANG); if (childpid>0) { childcount--; /* Se acaba de morir un hijo */ /* Muchas veces nos dará 0 si no se ha muerto ningún hijo, o -1 si no tenemos hijos con errno=10 (No child process). Así nos quitamos esos mensajes*/ if (WIFEXITED(pidstatus)) { /* Tal vez querremos mirar algo cuando se ha cerrado un hijo correctamente */ if (WEXITSTATUS(pidstatus)==99) { printf("\nSe ha pedido el cierre del programa\n"); activated=0; } } } loop++; } close(socket_host); return 0; }
int main(int *argc, char *argv[]) { //Declaracion de variables SOCKET sockfd; struct sockaddr_in server_in; char buffer_in[2048],comprueba[1024], buffer_out[2048]; int recibidos=0,enviados=0; int fallo_len=0; int estado; char option; int intentos; char username[30],destinatario[30],asunto[30],fecha[1024],mensaje[1024]="",entrada [1024]="."; WORD wVersionRequested; WSADATA wsaData; int err; int salir; struct hostent *host; struct in_addr address; int ipdestl; char ipdest[16]; char default_ip[16]="127.0.0.1"; system("color 0F"); //Inicialización Windows sockets wVersionRequested=MAKEWORD(1,1); err=WSAStartup(wVersionRequested,&wsaData); if(err!=0) return(0); if(LOBYTE(wsaData.wVersion)!=1||HIBYTE(wsaData.wVersion)!=1) { WSACleanup(); return(0); } //Fin: Inicialización Windows sockets do{ sockfd=socket(AF_INET,SOCK_STREAM,0); //Creación del socket if(sockfd==INVALID_SOCKET)//Comprobación de posible fallo { printf("ERROR AL CREAR SOCKET\r\n"); exit(-1); } else { do{ system("cls"); head(); printf("Introduzca la IP del servidor SMTP (pulsar enter para IP por defecto): "); gets(ipdest); if (strncmp(ipdest,"QUIT",4)==0){ return 1; } else{ salir=1; ipdestl=inet_addr(ipdest); if (ipdestl==INADDR_NONE){ host=gethostbyname(ipdest); if (host!=NULL){ memcpy(&address,host->h_addr_list[0],4); server_in.sin_addr=address; //IP del servidor } else{ printf("Error dominio incorrecto\r\n"); system("pause null"); salir=0; } } else { if (strcmp(ipdest,"")==0){ strcpy(ipdest,default_ip); } server_in.sin_addr.s_addr=inet_addr(ipdest);//IP del servidor } } }while(salir==0); printf("%s\r\n",inet_ntoa(server_in.sin_addr)); system("pause>nul"); //Parametros iniciales server_in.sin_family=AF_INET; //Familia IP server_in.sin_port=htons(TCP_SERVICE_PORT); //Puerto Que vamos a usar enviados=0; estado=S_HELO; intentos=0; // establece la conexion de transporte if(connect(sockfd,(struct sockaddr*)&server_in,sizeof(server_in))==0) { //Recibo recibidos=recv(sockfd,buffer_in,512,0); if(recibidos<=0){ DWORD error=GetLastError(); if(recibidos<0) { printf("Error %d en la recepción de datos\r\n",error); estado=S_QUIT; } else { printf("Conexión con el servidor cerrada\r\n"); estado=S_QUIT; } } do{ //MAQUINA DE ESTADOS switch(estado) { case S_RSET: sprintf_s(buffer_out,sizeof(buffer_out),"%s%s",RS,CRLF); system("cls"); head(); estado=S_HELO; break; case S_HELO: system("cls"); head(); sprintf_s(buffer_out,sizeof(buffer_out),"%s%s",HI,CRLF); break; case S_USER: printf("Username: "******"MAIL FROM:<%s>%s",username,CRLF); break; case S_ADDRESSEE: printf("Destinatario: "); gets(destinatario); sprintf_s(buffer_out,sizeof(buffer_out),"RCPT TO:<%s>%s",destinatario,CRLF); break; case S_DATA: sprintf_s(buffer_out,sizeof(buffer_out),"DATA%s",CRLF); break; case S_MENSAJE: //Fecha origen reloj(fecha); //Asunto printf("\nAsunto: "); gets(asunto); //Cabeceras del mensaje sprintf_s(mensaje,sizeof(mensaje),"Date: %s%sFrom: %s%sTo: %s%sSubject: %s%s",fecha,CRLF,username,CRLF,destinatario,CRLF,asunto,CRLF); printf("\nMENSAJE: (escribe un '.' para finalizar)\r\n"); do{ gets(entrada); sprintf_s(mensaje,sizeof(mensaje),"%s%s%s",mensaje,CRLF,entrada); }while(strncmp(entrada,".",1)!=0); sprintf_s(buffer_out,sizeof(mensaje),"%s%s",mensaje,CRLF); break; } //Envio enviados=send(sockfd,buffer_out,(int)strlen(buffer_out),0); if (enviados<0){ DWORD error=GetLastError(); printf("Error %d en el envio de datos%s",error,CRLF); break; } //Recibo recibidos=recv(sockfd,buffer_in,512,0); if(recibidos<=0){ DWORD error=GetLastError(); if(recibidos<0) { printf("Error %d en la recepción de datos\r\n",error); estado=S_QUIT; } else { printf("Conexión con el servidor cerrada\r\n"); estado=S_QUIT; } } if (strncmp(buffer_in,"554",3)==0){ printf("\nDicho destinatario no existe, reintentelo\r\n\n"); } if (estado==S_MENSAJE && strncmp(buffer_in,"250",3)==0){ char op; system("cls"); head(); printf("Mensaje enviado correctamente\r\n\n"); printf("Desea enviar otro mensaje[S/N]"); op=_getche(); if (op=='S' || op=='s'){ estado=S_RSET; } else{ system("cls"); head(); estado=S_QUIT; } } //Avance de estado else if(strncmp(buffer_in,"2",1)==0 || strncmp(buffer_in,"3",1)==0){ estado++; } }while(estado!=S_QUIT); } else //Error al Conectar { printf("ERROR AL CONECTAR CON %s:%d\r\n",ipdest,TCP_SERVICE_PORT); } // fin de la conexion de transporte closesocket(sockfd); } printf("Volver a conectar, con este u otro cliente(S/N)\r\n"); option=_getche(); //realizar otra conexión }while(option!='n' && option!='N'); return(0); }