//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;
}
Beispiel #2
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);

}