1 /* LibTcp - Released underOpen Software License v. 2.0
3 * This Open Software License (the "License") applies to any original work of authorship
4 * (the "Original Work") whose owner (the "Licensor") has placed the following notice
5 * immediately following the copyright notice for the Original Work:
7 * Licensed under the Open Software License version 2.0
9 * See http://www.opensource.org/licenses/osl-2.0.php or the LICENSE file for more
15 /** Abre un socket en modo activo para establecer una conexión con un servidor.
17 * Esta función es utilizada por los clientes para establecer una conexión TCP
20 * \param servidor Nombre del host server
21 * \param port Número del puerto
22 * \return >0 El descriptor del socket, si se conecto al servidor.
23 * \return -2 Si no existe el nombre del servidor.
24 * \return -1 Si hubo error en la conexion y se debe consultar errno.
26 int libtcp_open_activo (const char *server, int port)
28 int sockfd; /* socket de la conexion */
29 struct sockaddr_in serv_addr;
30 struct hostent *ptr_server; /*puntero a dir del server(gethostbyname)*/
32 /* Borrar la estructura (poner en cero) */
33 bzero ((char *) &serv_addr, sizeof(serv_addr));
35 /* Inicializo familia de direcciones (protocolo IP) */
36 serv_addr.sin_family = AF_INET;
38 /* Cargar port en el socket: Convertir Host-TO-Network-Short integer */
39 serv_addr.sin_port = htons (port);
41 /* Cargo dirección del server en el socket. Convertir nombre del host en su direccion */
42 ptr_server = gethostbyname (server);
43 if (ptr_server == NULL) {
44 /* No existe nombre de host. Posible falla en resolución de nombre */
47 memcpy (&serv_addr.sin_addr, ptr_server->h_addr, ptr_server->h_length);
49 /* Abro como un socket de TCP (Internet stream socket) */
50 if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) < 0) {
51 /* Error en la creacion del socket */
55 if (connect (sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
56 /* TODO : Deberia ser un codigo de error diferente, asi puedo diferenciarlos */
63 /** Abre un socket en modo pasivo usando protocolo TCP.
65 * La función se encarga de inicializar y crear el socket, y
66 * luego enlazarla con el SO.
68 * \param port Puerto sobre el cual atiende este servidor
69 * \return >0 El socket, si la operacion fue exitosa
70 * \return <0 Si hubo un error (ver errno)
72 int libtcp_open_pasivo (int port)
74 char mostrar[80]; /* mensajes en la pantalla */
75 int sockfd; /* socket que sirve como template */
76 struct sockaddr_in serv_addr;
78 bzero ((char *)&serv_addr, sizeof (serv_addr));
79 serv_addr.sin_family = AF_INET; /* Familia protocolos TCP/IP */
80 serv_addr.sin_addr.s_addr = htonl (INADDR_ANY); /* Cualquier cliente */
81 serv_addr.sin_port = htons ((u_short)port); /* Port en formato red */
83 /* Crea un socket para TCP (un Internet stream socket) */
84 if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) < 0) {
88 sprintf (mostrar, "LibTcp::ServerPasivo: socket creado %d\n", sockfd);
89 write (fileno(stdout), mostrar, strlen (mostrar));
91 /* Vincular el socket con la direccion local */
92 if (bind (sockfd, (struct sockaddr *) &serv_addr, sizeof (serv_addr)) < 0) {
96 sprintf (mostrar, "LibTcp::Server: se hizo el bind\n");
97 write(fileno(stdout), mostrar, strlen(mostrar));
99 /* Definir la cola de espera = hasta 5 clientes */
102 sprintf (mostrar, "LibTcp::Server: se hizo el listen con el socket %d\n", sockfd);
103 write(fileno(stdout), mostrar, strlen(mostrar));
108 /** Lee de a un byte por vez a un buffer hasta encontrar un "\n".
110 * La cadena leída es terminada en "\0".
112 * \return El tamaño, en caracteres, de la cadena leida.
113 * \param fd Descriptor del socket
114 * \param ptr Puntero al buffer
115 * \param maxlong Tamaño del buffer (en bytes)
116 * \TODO Soporte de caracteres multibyte
118 int libtcp_receive (int fd, char *ptr, unsigned int maxlong)
123 for (n = 0; n < maxlong; n++) {
124 if ((car = read (fd, &c, sizeof (char))) == 1) {
128 } else if (car == 0) {
130 /* EOF, sin datos leidos */
133 break; /* EOF, se leyo algo */
142 /** Lee una informacion binaria */
143 int libtcp_receive_bin (int fd, void *ptr, unsigned int maxlong)
145 return read (fd, ptr, maxlong);
149 /** Escribe n bytes sobre un descriptor.
151 * Si no se escribieron n bytes, trata de repetir hasta que se hayan escrito
154 * Se debe usar esta funcion cuando el descriptor en un stream socket.
156 * \param fd Descriptor del socket
157 * \param ptr Puntero al mensaje
158 * \param n cantidad de bytes
160 int libtcp_send (int fd, const char *ptr, unsigned int n)
162 int nfaltan, nenviados;
165 while (nfaltan > 0) {
166 nenviados = write (fd, ptr, nfaltan);
170 nfaltan -= nenviados;