Si te digo la verdad, no sabria crear una ventada de consola....pero si este es tu problema...
Yo lo que haria, seria pedir los datos y luego lipiar la pantalla con system("cls"); Esta funcion del sistema borra todo lo que tengas escrito en la pantalla. Puedes probar el "cls" en el ms dos y veras que borra todo lo que llevabas escrito y luego te vuelve a imprimir el prompt (C:\Documents.....\....\).
NOTA: para poder usar system(""); debes incluir stdlib.h
Espero haberte servido de ayuda, un saludo!
OK gracias!, aunque seguiré investigando.
EDITADOVoy a colocar el código fuente mejor, para que si alguien tiene una idea de como resolver mi problema sin tener que crear una nueva ventana.
Para que puedan compilarlo, van a tener que agregar un comando del linker. que es
-lws2_32. En del Dev-C++ tienen que hacerlo asi:
Herramientas>opciones del compilador>añadir estos comandos a la lista de comandos del linker, seleccionan la casilla y le dan aceptar.
Para POHw xdCliente.c#include <stdio.h>
#include <winsock2.h>
#include <string.h>
#include <process.h>
#define _NOCURSOR 0
#define _SOLIDCURSOR 1
#define _NORMALCURSOR 2
void _setcursortype ( int );
void gotoxy ( int x, int y );
void delline (int coordY);
void clrscr ( );
void Rutina1 (void *p);
void Rutina2 (void *p);
void Lanzar ();
HANDLE pPID[3];
char Buffer[1023];
char nombre[100];
char SuNombre[100];
int len;
SOCKET sock;
int main()
{
WSADATA wsa;
struct hostent *host;
struct sockaddr_in direc;
int conex;
char hosting[100];
//Inicializamos
WSAStartup (MAKEWORD (2, 2), &wsa);
//resolvemos el nombre de dominio localhost, esto se resolverá a 127.0.0.1
printf ( "ingrese su nombre: " ); scanf ( "%[^\n]", nombre
);
printf ( "ingrese la ip publica del servidor: " ); scanf ( "%[^\n]", hosting
);
if ( (host = gethostbyname ( hosting )) == NULL )
{
printf ( "problemas con el host: %s\n", hosting
);
closesocket(sock);/*cierra el socket*/
WSACleanup();
return -1;
}
//creamos el socket
sock = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock == -1)
{
printf("Error al crear el socket");
closesocket(sock);/*cierra el socket*/
WSACleanup();
return -1;
}
//Definimos la dirección a conectar que hemos recibido desde el gethostbyname
//y decimos que el puerto al que deberá conectar es el 9999 con el protocolo ipv4
direc.sin_family = AF_INET;
direc.sin_port = htons (9599);
direc.sin_addr = *((struct in_addr *)host->h_addr);
memset (direc.
sin_zero, 0, 8); //Intentamos establecer la conexión
conex = connect(sock,(struct sockaddr *)&direc, sizeof(struct sockaddr));
if (conex == -1) //si no se ha podido conectar porque no se ha encontrado el host o no
//está el puerto abierto
{
printf("No se ha podido conectar\n");
shutdown (sock, SD_BOTH);
closesocket(sock);/*cierra el socket*/
WSACleanup();
return -1;
}
printf ( "Esperamos a que el servidor termine de aceptar la solicitud\n" );
/*recibimos el nombre del cliente*/
len = 0;
if( (len = recv ( sock, SuNombre, sizeof (SuNombre), 0 )) == -1 )
{
printf ( "error al recibir el buffer\n" );
shutdown (sock, SD_BOTH);
closesocket (sock);/*cierra el socket*/
WSACleanup ();
return -1;
}
SuNombre[len] = '\0'; /*ponemos el fin de cadena*/
/*enviamos nuestro nombre*/
if ( (len
= send
( sock
, nombre
, strlen (nombre
), 0 )) == -1 ) {
printf ( "error al enviar el buffer\n" );
shutdown (sock, SD_BOTH);
closesocket (sock);/*cierra el socket*/
WSACleanup ();
return -1;
}
clrscr ( );
printf("[escribe el texto a enviar o 'salir' para salir ]\n\n");
Lanzar ();
ResumeThread (pPID[0]);
Sleep(1);
ResumeThread (pPID[1]);
Sleep(1);
WaitForMultipleObjects (2, pPID, FALSE, INFINITE);
_setcursortype ( _NORMALCURSOR );
closesocket (sock);
WSACleanup ();
return 0;
}
void Lanzar ()
{
pPID[0] = (HANDLE)_beginthreadex (NULL, 0, (void *)Rutina1, 0, CREATE_SUSPENDED, NULL);
pPID[1] = (HANDLE)_beginthreadex (NULL, 0, (void *)Rutina2, 0, CREATE_SUSPENDED, NULL);
}
void Rutina1 (void *p)
{
_setcursortype ( _NOCURSOR );
while ( 1 )
{
WaitForSingleObject (&pPID[0], INFINITE);
len = 0;
len = recv (sock, Buffer, 1023, 0); //recibimos los datos que envie
if (len == 0)
{
printf ( "el %s cerró la conexion\n", SuNombre
); shutdown (sock, SD_BOTH);
return ;
}
else
{
if (len == SOCKET_ERROR)
{
printf ( "Error: %d", WSAGetLastError
() ); shutdown (sock, SD_BOTH);
return ;
}
else
{
if (len > 0) //si seguimos conectados
{
Buffer[len] = 0; //le ponemos el final de cadena
printf ( "\n%s dice: %s%s dice:", SuNombre
, Buffer
, nombre
); }
}
}
}
shutdown (sock, SD_BOTH);
return ;
}
void Rutina2 (void *p)
{
_setcursortype ( _SOLIDCURSOR );
while ( 1 )
{
WaitForSingleObject (&pPID[1], INFINITE);
printf ( "%s dice: ", nombre
); fgets (Buffer
, 1023, stdin
); //pedir texto a enviar por pantalla
if (!strcmp (Buffer
, "salir\n")) {
SuspendThread (pPID[0]);
shutdown (sock, SD_BOTH);
return ;
}
else
send
(sock
, Buffer
, strlen(Buffer
), 0); //enviar el texto que se ha introducido }
return ;
}
void gotoxy ( int x, int y )
{
COORD coordenadas;
coordenadas.X = x;
coordenadas.Y = y;
SetConsoleCursorPosition ( GetStdHandle (STD_OUTPUT_HANDLE), coordenadas );
}
void delline (int coordY)
{
int i;
for (i = 80; i >= 0; i-- )
{
gotoxy (i, coordY);
}
return ;
}
void clrscr ( )
{
HANDLE hStdOut = GetStdHandle ( STD_OUTPUT_HANDLE );
COORD coord = { 0, 0 };
DWORD count;
CONSOLE_SCREEN_BUFFER_INFO csbi;
GetConsoleScreenBufferInfo ( hStdOut, &csbi );
FillConsoleOutputCharacter ( hStdOut, ' ', csbi.dwSize.X * csbi.dwSize.Y, coord, &count );
SetConsoleCursorPosition ( hStdOut, coord );
}
void _setcursortype ( int cursor )
{
CONSOLE_CURSOR_INFO cur;
switch (cursor)
{
case _NOCURSOR:
cur.dwSize = 1;
cur.bVisible = FALSE;
break;
case _SOLIDCURSOR:
cur.dwSize = 100;
cur.bVisible = TRUE;
break;
case _NORMALCURSOR:
cur.dwSize = 10;
cur.bVisible = TRUE;
break;
}
SetConsoleCursorInfo ( GetStdHandle ( STD_OUTPUT_HANDLE ), &cur );
}
{
char car;
DWORD leidos, modo;
GetConsoleMode ( GetStdHandle (STD_INPUT_HANDLE), &modo );
SetConsoleMode ( GetStdHandle (STD_INPUT_HANDLE), modo &
!ENABLE_ECHO_INPUT & !ENABLE_PROCESSED_INPUT );
ReadConsole ( GetStdHandle (STD_INPUT_HANDLE), &car, 1, &leidos, NULL );
SetConsoleMode ( GetStdHandle (STD_INPUT_HANDLE), modo );
return car;
}
Servidor.c#include <winsock2.h>
#include <stdio.h>
#include <windows.h>
#include <process.h>
#include <string.h>
#define _NOCURSOR 0
#define _SOLIDCURSOR 1
#define _NORMALCURSOR 2
void _setcursortype ( int );
void gotoxy ( int x, int y );
void delline (int coordY);
void clrscr ( );
void delline ();
void Rutina1 (void *p);
void Rutina2 (void *p);
void Lanzar ();
HANDLE pPID[3];
char Buffer[1023];
char nombre[100];
char SuNombre[100];
int len = 0;
SOCKET sock;
int main ( )
{
WSADATA wsa;
struct sockaddr_in local;
//Inicializamos
WSAStartup (MAKEWORD (2, 0), &wsa);
//Creamos el socket
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
//defnimos dirección por defecto, ipv4 y el puerto 9999
local.sin_family = AF_INET;
local.sin_addr.s_addr = INADDR_ANY;
local.sin_port = htons(9599);
//asociamos el socket al puerto
if (bind(sock, (SOCKADDR*) &local, sizeof(local)) == -1)
{
printf ( "error en el bind\n" );
closesocket (sock);/*cierra el socket*/
WSACleanup ();
return -1;
}
//ponemos el socket a la escucha
if (listen(sock, 1) == -1)
{
printf ( "error en el listen\n" );
closesocket (sock);/*cierra el socket*/
WSACleanup ();
return -1;
}
len = sizeof (struct sockaddr);
clrscr ( );
printf ( "Esperando la conexion..." ); //hay una conexión entrante y la aceptamos
sock = accept (sock, (struct sockaddr*)&local, &len);
delline (0);
printf ( "La conexion se ha establecido con exito\n\n" );
printf ( "Ingrese su nombre: " ); scanf ( "%[^\n]", nombre
);
printf("\tMinichat en Desarrollo\n\n");
/*enviamos nuestro nombre*/
if ( (len
= send
( sock
, nombre
, strlen (nombre
), 0 )) == -1 ) {
printf ( "error al enviar el buffer\n" ); shutdown (sock, SD_BOTH);
WSACleanup();
closesocket(sock);/*cierra el socket*/
return -1;
}
/*recibimos el nombre del cliente*/
len = 0;
if( (len = recv ( sock, SuNombre, sizeof (SuNombre), 0 )) == -1 )
{
printf ( "error al recibir el buffer\n" ); shutdown (sock, SD_BOTH);
WSACleanup();
closesocket(sock);/*cierra el socket*/
return -1;
}
SuNombre[len] = '\0';/*ponemos el fin de cadena*/
Lanzar ();/*creamos los 2 hilos que vamos a usar, pero como suspendidos*/
ResumeThread (pPID[0]);/*vuelve a lanzar el hilo*/
Sleep(1);
ResumeThread (pPID[1]);
Sleep(1);
WaitForMultipleObjects (2, pPID, FALSE, INFINITE);/*espera a que los 2 hilos terminen*/
_setcursortype ( _NORMALCURSOR );
closesocket(sock);
WSACleanup();
return 0;
}
void Lanzar ()
{
pPID[0] = (HANDLE)_beginthreadex (NULL/*&saAttr*/, 0, (void *)Rutina1, 0, CREATE_SUSPENDED, NULL);
pPID[1] = (HANDLE)_beginthreadex (NULL/*&saAttr*/, 0, (void *)Rutina2, 0, CREATE_SUSPENDED, NULL);
}
void Rutina1 (void *p)
{
//mientras estemos conectados con el otro pc
_setcursortype ( _NOCURSOR );
while (/*strcmp (Buffer, "salir\n") != 0*/1)
{
WaitForSingleObject (&pPID[0], INFINITE);
len = 0;
len = recv (sock, Buffer, 1023, 0); //recibimos los datos que envie
if (len == 0)
{
printf ( "el %s cerró la conexion\n", SuNombre
); shutdown (sock, SD_BOTH);
return ;
}
else
{
if (len == SOCKET_ERROR)
{
printf ( "Error: %d", WSAGetLastError
() ); shutdown (sock, SD_BOTH);
return ;
}
else
{
if (len > 0) //si seguimos conectados
{
Buffer[len] = 0; //le ponemos el final de cadena
printf ( "\n%s dice: %s%s dice:", SuNombre
, Buffer
, nombre
); }
}
}
}
shutdown (sock, SD_BOTH);
return ;
}
void Rutina2 (void *p)
{
_setcursortype ( _SOLIDCURSOR );
while ( 1 )
{
WaitForSingleObject (&pPID[1], INFINITE);
printf ( "%s dice: ", nombre
); fgets (Buffer
, 1023, stdin
); //pedir texto a enviar por pantalla
if ( !strcmp (Buffer
, "salir\n") ) {
SuspendThread (pPID[0]);
shutdown (sock, SD_BOTH);
return ;
}
else
send
(sock
, Buffer
, strlen(Buffer
), 0); //enviar el texto que se ha introducido }
return ;
}
void gotoxy ( int x, int y )
{
COORD coordenadas;
coordenadas.X = x;
coordenadas.Y = y;
SetConsoleCursorPosition ( GetStdHandle (STD_OUTPUT_HANDLE), coordenadas );
}
void delline (int coordY)
{
int i;
for (i = 80; i >= 0; i-- )
{
gotoxy (i, coordY);
}
return ;
}
void clrscr ( )
{
HANDLE hStdOut = GetStdHandle ( STD_OUTPUT_HANDLE );
COORD coord = { 0, 0 };
DWORD count;
CONSOLE_SCREEN_BUFFER_INFO csbi;
GetConsoleScreenBufferInfo ( hStdOut, &csbi );
FillConsoleOutputCharacter ( hStdOut, ' ', csbi.dwSize.X * csbi.dwSize.Y, coord, &count );
SetConsoleCursorPosition ( hStdOut, coord );
}
void _setcursortype ( int cursor )
{
CONSOLE_CURSOR_INFO cur;
switch (cursor)
{
case _NOCURSOR:
cur.dwSize = 1;
cur.bVisible = FALSE;
break;
case _SOLIDCURSOR:
cur.dwSize = 100;
cur.bVisible = TRUE;
break;
case _NORMALCURSOR:
cur.dwSize = 10;
cur.bVisible = TRUE;
break;
}
SetConsoleCursorInfo ( GetStdHandle ( STD_OUTPUT_HANDLE ), &cur );
}
{
char car;
DWORD leidos, modo;
GetConsoleMode ( GetStdHandle (STD_INPUT_HANDLE), &modo );
SetConsoleMode ( GetStdHandle (STD_INPUT_HANDLE), modo &
!ENABLE_ECHO_INPUT & !ENABLE_PROCESSED_INPUT );
ReadConsole ( GetStdHandle (STD_INPUT_HANDLE), &car, 1, &leidos, NULL );
SetConsoleMode ( GetStdHandle (STD_INPUT_HANDLE), modo );
return car;
}
Y para los quieran chatear por internet (No LAN), si el servidor usa una salida a internet por un router, van a tener que abrir el puerto
9999, cada router tiene una manera diferente de hacerlo, asi que mejor busquen como hacerlo para su router respectivo. Ojo, la ip que tienen que agregar es la ip publica, para la salida de internet, tambien pueden comprobarlo usando dos terminales de ms-dos usando
localhost como ip.
saludos!