⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 socket.c

📁 multiplataform real time Linux monitor
💻 C
字号:
/** Javier Abellan, 20 Jun 2000** Funciones de lectura y escritura en sockets** MODIFICACIONES:* 4 Septiembre 2003: Añadidas funciones para sockets UDP.*/#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h> #include <sys/un.h>#include <netdb.h>#include <unistd.h>#include <errno.h>#include <stdio.h>#include "socket.h"/** Lee datos del socket. Supone que se le pasa un buffer con hueco *	suficiente para los datos. Devuelve el numero de bytes leidos o* 0 si se cierra fichero o -1 si hay error.*/int Lee_Socket (int fd, char *Datos, int Longitud){	int Leido = 0;	int Aux = 0;	/*	* Comprobacion de que los parametros de entrada son correctos	*/	if ((fd == -1) || (Datos == NULL) || (Longitud < 1))		return -1;	/*	* Mientras no hayamos leido todos los datos solicitados	*/	while (Leido < Longitud)	{		Aux = read (fd, Datos + Leido, Longitud - Leido);		if (Aux > 0)		{			/* 			* Si hemos conseguido leer datos, incrementamos la variable			* que contiene los datos leidos hasta el momento			*/			Leido = Leido + Aux;		}		else		{			/*			* Si read devuelve 0, es que se ha cerrado el socket. Devolvemos			* los caracteres leidos hasta ese momento			*/			if (Aux == 0) 				return Leido;			if (Aux == -1)			{				/*				* En caso de error, la variable errno nos indica el tipo				* de error. 				* El error EINTR se produce si ha habido alguna				* interrupcion del sistema antes de leer ningun dato. No				* es un error realmente.				* El error EGAIN significa que el socket no esta disponible				* de momento, que lo intentemos dentro de un rato.				* Ambos errores se tratan con una espera de 100 microsegundos				* y se vuelve a intentar.				* El resto de los posibles errores provocan que salgamos de 				* la funcion con error.				*/				switch (errno)				{					case EINTR:					case EAGAIN:						usleep (100);						break;					default:						return -1;				}			}		}	}	/*	* Se devuelve el total de los caracteres leidos	*/	return Leido;}/** Escribe dato en el socket cliente. Devuelve numero de bytes escritos,* o -1 si hay error.*/int Escribe_Socket (int fd, char *Datos, int Longitud){	int Escrito = 0;	int Aux = 0;	/*	* Comprobacion de los parametros de entrada	*/	if ((fd == -1) || (Datos == NULL) || (Longitud < 1))		return -1;	/*	* Bucle hasta que hayamos escrito todos los caracteres que nos han	* indicado.	*/	while (Escrito < Longitud)	{		Aux = write (fd, Datos + Escrito, Longitud - Escrito);		if (Aux > 0)		{			/*			* Si hemos conseguido escribir caracteres, se actualiza la			* variable Escrito			*/			Escrito = Escrito + Aux;		}		else		{			/*			* Si se ha cerrado el socket, devolvemos el numero de caracteres			* leidos.			* Si ha habido error, devolvemos -1			*/			if (Aux == 0)				return Escrito;			else				return -1;		}	}	/*	* Devolvemos el total de caracteres leidos	*/	return Escrito;}/** * Lee un mensaje de un socket udp. Los parametros que se pasan son: * - Descriptor fd del socket del que se quiere leer. * - Estructura Remoto, en la que se devolvera los datos del que ha enviado el * mensaje que acabamos de leer. * - Longitud_Remoto de la estructura anterior. Debe pasarse relleno con el tamaño * de Remoto y se devolvera rellena con el tamaño de los datos en Remoto. * - Buffer de Datos donde se quiere que aparezca el mensaje. * - Longitud_Datos del buffer anterior. * * Devuelve el numero de bytes leidos o -1 en caso de error. */int Lee_Socket_Udp (	int fd, struct sockaddr *Remoto, socklen_t *Longitud_Remoto,	char *Datos, int Longitud_Datos){	int Leido = 0;	int Aux = 0;	/*	* Comprobacion de que los parametros de entrada son correctos	*/	if ((fd == -1) || (Datos == NULL) || (Longitud_Datos < 1)			|| (Remoto == NULL) || (Longitud_Remoto == NULL))	{		return -1;	}	/*	* Mientras no hayamos leido todos los datos solicitados	*/	while (Leido < Longitud_Datos)	{		Aux = recvfrom (fd, Datos + Leido, Longitud_Datos - Leido, 0,			Remoto, Longitud_Remoto);		if (Aux > 0)		{			/* 			* Si hemos conseguido leer datos, incrementamos la variable			* que contiene los datos leidos hasta el momento			*/			Leido = Leido + Aux;		}		else		{			/*			* Si read devuelve 0, es que se ha cerrado el socket. Devolvemos			* los caracteres leidos hasta ese momento			*/			if (Aux == 0) 				return Leido;			if (Aux == -1)			{				/*				* En caso de error, la variable errno nos indica el tipo				* de error. 				* El error EINTR se produce si ha habido alguna				* interrupcion del sistema antes de leer ningun dato. No				* es un error realmente.				* El error EGAIN significa que el socket no esta disponible				* de momento, que lo intentemos dentro de un rato.				* Ambos errores se tratan con una espera de 100 microsegundos				* y se vuelve a intentar.				* El resto de los posibles errores provocan que salgamos de 				* la funcion con error.				*/				switch (errno)				{					case EINTR:					case EAGAIN:						usleep (100);						break;					default:						return -1;				}			}		}	}	/*	* Se devuelve el total de los caracteres leidos	*/	return Leido;}/*** Escribe dato en el socket cliente. Devuelve numero de bytes escritos,* o -1 si hay error.* - fd es el descriptor del socket.* - Remoto es el destinatario del mensaje, a quien se lo queremos enviar. * - Longitud_Remoto es el tamaño de Remoto en bytes.* - Datos es el mensaje que queremos enviar.* - Longitud_Datos es el tamaño del mensaje en bytes.*/int Escribe_Socket_Udp (int fd, struct sockaddr *Remoto, 	socklen_t Longitud_Remoto, char *Datos, int Longitud_Datos){	int Escrito = 0;	int Aux = 0;	/*	* Comprobacion de los parametros de entrada	*/	if ((fd == -1) || (Datos == NULL) || (Longitud_Datos < 1) 			|| (Remoto == NULL) )   {		return -1;   }	/*	* Bucle hasta que hayamos escrito todos los caracteres que nos han	* indicado.	*/	while (Escrito < Longitud_Datos)	{		Aux = sendto (fd, Datos + Escrito, Longitud_Datos - Escrito, 0,			Remoto, Longitud_Remoto);		if (Aux > 0)		{			/*			* Si hemos conseguido escribir caracteres, se actualiza la			* variable Escrito			*/			Escrito = Escrito + Aux;		}		else		{			/*			* Si se ha cerrado el socket, devolvemos el numero de caracteres			* leidos.			* Si ha habido error, devolvemos -1			*/			if (Aux == 0)				return Escrito;			else         {				return -1;         }		}	}	/*	* Devolvemos el total de caracteres leidos	*/	return Escrito;}/** * Rellena una estructura sockaddr_in con los datos que se le pasan. Esta estrutura es * util para el envio o recepcion de mensajes por sockets Udp o para abrir conexiones. * Se le pasa el host. Puede ser NULL (para abrir socket servidor Udp o para recepcion de * mensajes de cualquier host). * Se le pasa el servicio. Puede ser NULL (para abrir socket cliente Udp). * Se le pasa una estructura sockaddr_in que devolvera rellena. * Se le pasa una Longitud. Debe contener el tamaño de la estructura sockaddr_in y * devolvera el tamaño de la estructura una vez rellena. * Devuelve -1 en caso de error. */int Dame_Direccion_Udp (char *Host, char *Servicio, struct sockaddr_in *Servidor,   int *Longitud_Servidor){   struct servent *Puerto;   struct hostent *Maquina;     /* Comprobacion de parametros */   if (Servidor == NULL) return -1;   /* Relleno del primer campo de la estructura */   Servidor->sin_family = AF_INET;   /* Si nos han pasado un host ... */   if (Host != NULL)   {      /* ... obtenemos la direccion del host y la ponemos en la estructura */      Maquina = gethostbyname (Host);      if (Maquina == NULL)         return -1;      Servidor->sin_addr.s_addr = ((struct in_addr *)(Maquina->h_addr))->s_addr;   }   else      /* Si no nos han pasado un host, ponemos cualquier host. */      Servidor->sin_addr.s_addr = INADDR_ANY;   /* Si servicio en NULL, hacemos que el puerto lo eliga el sistema operativo    libremente.*/   if (Servicio == NULL)      Servidor->sin_port = 0;   else   {      /* Si el servicio no es NULL, lo obtenemos. */      Puerto = getservbyname (Servicio, "udp");      if (Puerto == NULL)         return -1;      Servidor->sin_port = Puerto->s_port;   }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -