fluid_server_socket_t* new_fluid_server_socket(int port, fluid_server_func_t func, void* data) { fluid_server_socket_t* server_socket; struct sockaddr_in addr; fluid_socket_t sock; g_return_val_if_fail (func != NULL, NULL); sock = socket(AF_INET, SOCK_STREAM, 0); if (sock == INVALID_SOCKET) { FLUID_LOG(FLUID_ERR, "Failed to create server socket"); return NULL; } FLUID_MEMSET((char *)&addr, 0, sizeof(struct sockaddr_in)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_ANY); addr.sin_port = htons(port); if (bind(sock, (const struct sockaddr *) &addr, sizeof(struct sockaddr_in)) == SOCKET_ERROR) { FLUID_LOG(FLUID_ERR, "Failed to bind server socket"); fluid_socket_close(sock); return NULL; } if (listen(sock, 10) == SOCKET_ERROR) { FLUID_LOG(FLUID_ERR, "Failed listen on server socket"); fluid_socket_close(sock); return NULL; } server_socket = FLUID_NEW(fluid_server_socket_t); if (server_socket == NULL) { FLUID_LOG(FLUID_ERR, "Out of memory"); fluid_socket_close(sock); return NULL; } server_socket->socket = sock; server_socket->func = func; server_socket->data = data; server_socket->cont = 1; server_socket->thread = new_fluid_thread(fluid_server_socket_run, server_socket, 0, FALSE); if (server_socket->thread == NULL) { FLUID_FREE(server_socket); fluid_socket_close(sock); return NULL; } return server_socket; }
static void fluid_server_socket_run (void *data) { fluid_server_socket_t *server_socket = (fluid_server_socket_t *)data; fluid_socket_t client_socket; struct sockaddr_in addr; socklen_t addrlen = sizeof (addr); int retval; FLUID_LOG (FLUID_DBG, "Server listening for connections"); while (server_socket->cont) { client_socket = accept (server_socket->socket, (struct sockaddr *)&addr, &addrlen); FLUID_LOG (FLUID_DBG, "New client connection"); if (client_socket == INVALID_SOCKET) { if (server_socket->cont) FLUID_LOG(FLUID_ERR, "Failed to accept connection"); server_socket->cont = 0; return; } else { retval = server_socket->func (server_socket->data, client_socket, inet_ntoa (addr.sin_addr)); // FIXME - inet_ntoa is not thread safe if (retval != 0) fluid_socket_close(client_socket); } } FLUID_LOG(FLUID_DBG, "Server closing"); }
int delete_fluid_server_socket(fluid_server_socket_t* server_socket) { server_socket->cont = 0; if (server_socket->socket != INVALID_SOCKET) { fluid_socket_close(server_socket->socket); } if (server_socket->thread) { delete_fluid_thread(server_socket->thread); } FLUID_FREE(server_socket); return FLUID_OK; }
int delete_fluid_server_socket(fluid_server_socket_t *server_socket) { server_socket->cont = 0; if (server_socket->socket != INVALID_SOCKET) fluid_socket_close (server_socket->socket); if (server_socket->thread) delete_fluid_thread (server_socket->thread); FLUID_FREE (server_socket); WSACleanup (); // Should be called the same number of times as WSAStartup return FLUID_OK; }
static void fluid_server_socket_run (void *data) { fluid_server_socket_t *server_socket = (fluid_server_socket_t *)data; fluid_socket_t client_socket; #ifdef IPV6 struct sockaddr_in6 addr; char straddr[INET6_ADDRSTRLEN]; #else struct sockaddr_in addr; char straddr[INET_ADDRSTRLEN]; #endif socklen_t addrlen = sizeof (addr); int retval; FLUID_MEMSET((char *)&addr, 0, sizeof(addr)); FLUID_LOG (FLUID_DBG, "Server listening for connections"); while (server_socket->cont) { client_socket = accept (server_socket->socket, (struct sockaddr *)&addr, &addrlen); FLUID_LOG (FLUID_DBG, "New client connection"); if (client_socket == INVALID_SOCKET) { if (server_socket->cont) FLUID_LOG(FLUID_ERR, "Failed to accept connection"); server_socket->cont = 0; return; } else { #ifdef IPV6 inet_ntop(AF_INET6, &addr.sin6_addr, straddr, sizeof(straddr)); #else inet_ntop(AF_INET, &addr.sin_addr, straddr, sizeof(straddr)); #endif retval = server_socket->func (server_socket->data, client_socket, straddr); if (retval != 0) fluid_socket_close(client_socket); } } FLUID_LOG(FLUID_DBG, "Server closing"); }
fluid_server_socket_t* new_fluid_server_socket(int port, fluid_server_func_t func, void* data) { fluid_server_socket_t* server_socket; #ifdef IPV6 struct sockaddr_in6 addr; #else struct sockaddr_in addr; #endif fluid_socket_t sock; WSADATA wsaData; int retval; if (func == NULL) { FLUID_LOG(FLUID_ERR, "func is NULL"); return NULL; } // Win32 requires initialization of winsock retval = WSAStartup (MAKEWORD (2,2), &wsaData); if (retval != 0) { FLUID_LOG(FLUID_ERR, "Server socket creation error: WSAStartup failed: %d", retval); return NULL; } #ifdef IPV6 sock = socket (AF_INET6, SOCK_STREAM, 0); if (sock == INVALID_SOCKET) { FLUID_LOG (FLUID_ERR, "Failed to create server socket: %ld", WSAGetLastError ()); WSACleanup (); return NULL; } addr.sin6_family = AF_INET6; addr.sin6_port = htons (port); addr.sin6_addr = in6addr_any; #else sock = socket (AF_INET, SOCK_STREAM, 0); if (sock == INVALID_SOCKET) { FLUID_LOG (FLUID_ERR, "Failed to create server socket: %ld", WSAGetLastError ()); WSACleanup (); return NULL; } addr.sin_family = AF_INET; addr.sin_port = htons (port); addr.sin_addr.s_addr = htonl (INADDR_ANY); #endif retval = bind (sock, (struct sockaddr *)&addr, sizeof (addr)); if (retval == SOCKET_ERROR) { FLUID_LOG (FLUID_ERR, "Failed to bind server socket: %ld", WSAGetLastError ()); fluid_socket_close (sock); WSACleanup (); return NULL; } if (listen (sock, SOMAXCONN) == SOCKET_ERROR) { FLUID_LOG (FLUID_ERR, "Failed to listen on server socket: %ld", WSAGetLastError ()); fluid_socket_close (sock); WSACleanup (); return NULL; } server_socket = FLUID_NEW (fluid_server_socket_t); if (server_socket == NULL) { FLUID_LOG (FLUID_ERR, "Out of memory"); fluid_socket_close (sock); WSACleanup (); return NULL; } server_socket->socket = sock; server_socket->func = func; server_socket->data = data; server_socket->cont = 1; server_socket->thread = new_fluid_thread("server", fluid_server_socket_run, server_socket, 0, FALSE); if (server_socket->thread == NULL) { FLUID_FREE (server_socket); fluid_socket_close (sock); WSACleanup (); return NULL; } return server_socket; }