Al final he conseguido que funcione pero quiero aprender a hacer bien las cosas y me gustaria que lo corrigiese alguien y me diga si hago algo mal y me pueda explicar como hacerlo correctamente.
Aquí está el código:
Servidor:
Código PHP:
#include <stdio.h>
#include <windows.h>
#define MAX_THREADS 2
typedef struct DatosServidor {
SOCKET conn_socket;
} DATOS_SERVIDOR;
DWORD WINAPI MyThreadFunction( LPVOID lpParam );
void ErrorHandler(char *NameFunction);
int main(int argc, char *argv[]){
//Necesarias para crear los hilos
DWORD dwThreadIdArray[MAX_THREADS];
HANDLE hThreadArray[MAX_THREADS];
int i;
//Necesarias para crear el servidor
DATOS_SERVIDOR datos;
WSADATA wsaData;
struct sockaddr_in server;
struct hostent *hp;
int resp;
//Inicializamos la DLL de sockets
resp=WSAStartup(MAKEWORD(1,0),&wsaData);
if(resp){
printf("Error al inicializar socket\n");
getchar();
return resp;
}
//Obtenemos la IP que usará nuestro servidor...
// en este caso localhost indica nuestra propia máquina...
hp=(struct hostent *)gethostbyname("localhost");
if(!hp){
printf("No se ha encontrado servidor...\n");
getchar();
WSACleanup();
return WSAGetLastError();
}
// Creamos el socket...
datos.conn_socket=socket(AF_INET,SOCK_STREAM, 0);
if(datos.conn_socket==INVALID_SOCKET) {
printf("Error al crear socket\n");
getchar();
WSACleanup();
return WSAGetLastError();
}
memset(&server, 0, sizeof(server)) ;
memcpy(&server.sin_addr, hp->h_addr, hp->h_length);
server.sin_family = hp->h_addrtype;
server.sin_port = htons(6000);
// Asociamos ip y puerto al socket
resp=bind(datos.conn_socket, (struct sockaddr *)&server, sizeof(server));
if(resp==SOCKET_ERROR){
printf("Error al asociar puerto e ip al socket\n");
closesocket(datos.conn_socket);
WSACleanup();
getchar();
return WSAGetLastError();
}
if(listen(datos.conn_socket, 1)==SOCKET_ERROR){
printf("Error al habilitar conexiones entrantes\n");
closesocket(datos.conn_socket);
WSACleanup();
getchar();
return WSAGetLastError();
}
printf("Esperando conexiones entrantes... \n");
for(i=0; i<MAX_THREADS; i++ )
{
// Creo el hilo para iniciar la ejecución en su función
hThreadArray[i] = CreateThread(
NULL, // default security attributes
0, // use default stack size
MyThreadFunction, // thread function name
&datos, // argument to thread function
0, // use default creation flags
&dwThreadIdArray[i]); // returns the thread identifier
// Compruebo el valor de retorno
// Si CreateThread falla, termino la ejecución
// Esto limpiará automáticamente los hilos y la memoria
if (hThreadArray[i] == NULL)
{
ErrorHandler("CreateThread");
getchar();
return 3;
}
} // Fin del bucle de creacion de hilos
// Espero a que terminen todos los hilos
WaitForMultipleObjects(MAX_THREADS, hThreadArray, TRUE, INFINITE);
// Como no vamos a aceptar más conexiones cerramos el socket escucha
closesocket(datos.conn_socket);
// Cerramos liberia winsock
WSACleanup();
// Cierro todos los handles de los hilos
for(i=0; i<MAX_THREADS; i++)
{
CloseHandle(hThreadArray[i]);
}
printf("Fin de recepcion de mensajes");
getchar();
return (EXIT_SUCCESS);
}
DWORD WINAPI MyThreadFunction( LPVOID lpParam )
{
char RecvBuff[100];
SOCKET comm_socket;
DATOS_SERVIDOR *datos;
struct sockaddr_in client;
int stsize;
datos=(DATOS_SERVIDOR*)lpParam;
// Aceptamos conexiones entrantes
stsize=sizeof(struct sockaddr);
comm_socket=accept(datos->conn_socket,(struct sockaddr *)&client,&stsize);
if(comm_socket==INVALID_SOCKET){
printf("Error al aceptar conexión entrante\n");
getchar();
return WSAGetLastError();
}
printf("Conexion entrante desde: %s\n", inet_ntoa(client.sin_addr));
printf("Recibiendo Mensajes... \n");
recv (comm_socket, RecvBuff, sizeof(RecvBuff), 0);
printf("Datos recibidos: %s \n", RecvBuff);
// Cerramos el socket de la comunicacion
closesocket(comm_socket);
return 0;
}
void ErrorHandler(char *NameFunction)
{
LPVOID lpMsgBuf;
DWORD dw = GetLastError();
// Recupero el mensaje de error del sistema para el último error ocurrido
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0, NULL );
// Muestro el mensaje de error
printf("Error: %s failed with error %d: %s",NameFunction, dw, lpMsgBuf);
// Libero la memoria allocada
LocalFree(lpMsgBuf);
}
Cliente:
Código PHP:
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
int main(int argc, char *argv[]){
WSADATA wsaData;
SOCKET conn_socket;
struct sockaddr_in server;
struct hostent *hp;
int resp,salida;
unsigned long inicio,fin,lapso;
char SendBuff[100];
HWND windowHandle;
DWORD processID;
//Obtengo el tiempo en el que inicia el proceso
inicio=GetTickCount();
//Inicializamos la DLL de sockets
resp=WSAStartup(MAKEWORD(1,0),&wsaData);
if(resp){
printf("Error al inicializar socket\n");
getchar();
return -1;
}
//Obtenemos la IP del servidor... en este caso
// localhost indica nuestra propia máquina...
hp=(struct hostent *)gethostbyname("localhost");
if(!hp){
printf("No se ha encontrado servidor...\n");
getchar();
WSACleanup();
return WSAGetLastError();
}
// Creamos el socket...
conn_socket=socket(AF_INET,SOCK_STREAM, 0);
if(conn_socket==INVALID_SOCKET) {
printf("Error al crear socket\n");
getchar();
WSACleanup();
return WSAGetLastError();
}
memset(&server, 0, sizeof(server)) ;
memcpy(&server.sin_addr, hp->h_addr, hp->h_length);
server.sin_family = hp->h_addrtype;
server.sin_port = htons(6000);
// Nos conectamos con el servidor...
if(connect(conn_socket,(struct sockaddr *)&server,sizeof(server))==SOCKET_ERROR){
printf("Fallo al conectarse con el servidor\n");
closesocket(conn_socket);
WSACleanup();
getchar();
return WSAGetLastError();
}
printf("Conexion establecida con: %s\n", inet_ntoa(server.sin_addr));
//Esto lo pongo para tener una salida del proceso aleatoria
//No es necesaria para nada pero al menos asi consigo simular
//que el proceso hace algo mas a parte de comunicarse
srand(time(NULL));
do{
salida = rand()%1000;
Sleep(10);
}while(salida != 0);
//Obtengo el tiempo en que termina el proceso
fin=GetTickCount();
//Obtengo el lapso de tiempo transcurrido
lapso=fin-inicio;
processID = GetCurrentProcessId();
//Enviamos el lapso de tiempo que transcurrio...
printf("Enviando lapso de tiempo... \n");
sprintf(SendBuff,"El proceso con PID: %lu ha funcionado durante %lu milisegundos.",processID,lapso);
send(conn_socket,SendBuff,sizeof(SendBuff),0);
printf("Lapso enviado: %lu milisegundos\n", lapso);
// Cerramos el socket y liberamos la DLL de sockets
closesocket(conn_socket);
WSACleanup();
getchar();
return EXIT_SUCCESS;
}
Gracias de antemano