Mercurial
view seobeo/s_linux_network.c @ 3:2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
| author | June Park <parkjune1995@gmail.com> |
|---|---|
| date | Wed, 24 Sep 2025 18:49:09 -0700 |
| parents | adcfad6e86fb |
| children | 0b3b4f5887bb |
line wrap: on
line source
#include "seobeo/seobeo.h" int Seobeo_CreateSocket(int32 stream, char* port, int32 backlog) { int32 sock_fd; struct addrinfo hints, *server_infos, *free_server_info; int32 yes = 1; // Need this for setsockopt memset(&hints, 0, sizeof(hints)); if (stream) { hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; hints.ai_flags = AI_PASSIVE; } else { hints.ai_family = AF_INET; hints.ai_socktype = SOCK_DGRAM; hints.ai_protocol = IPPROTO_UDP; hints.ai_flags = AI_PASSIVE; } if (getaddrinfo(NULL, port, &hints, &server_infos) != 0) { perror("getaddrinfo"); return -1; } for ( free_server_info = server_infos; free_server_info != NULL; free_server_info = free_server_info->ai_next ) { if ( (sock_fd = socket( free_server_info->ai_family, free_server_info->ai_socktype, free_server_info->ai_protocol )) == -1 ) { perror("socket"); continue; } if (setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) == -1) { perror("setsockopt"); continue; } if (bind(sock_fd, free_server_info->ai_addr, free_server_info->ai_addrlen) == -1) { close(sock_fd); perror("setsockopt"); continue; } // UDP should be non blocking if(!stream) { if (fcntl(sock_fd, F_SETFL, O_NONBLOCK) != 0) { close(sock_fd); perror("v_network: Couldn't make socket non-blocking\n"); return -1; } } // binded to a open server infos; break; } // No longer need these values freeaddrinfo(server_infos); if (free_server_info == NULL) { perror("No free server"); return -1; } // TCP listen if(stream) { if (listen(sock_fd, backlog) != 0) { perror("listen"); return -1; } } return sock_fd; } void Seobeo_ListenClient(int sock_fd, void (*handle_client)(int)) { int32 client_fd; struct sockaddr_storage client_addr; socklen_t sin_size; char client_inet_addr[INET6_ADDRSTRLEN]; while (1) { sin_size = sizeof(client_addr); client_fd = accept(sock_fd, (struct sockaddr *)&client_addr, &sin_size); if (client_fd == -1) { perror("accept"); break; } inet_ntop( client_addr.ss_family, Seobeo_GetIP4OrIP6((struct sockaddr *)&client_addr), client_inet_addr, sizeof client_inet_addr); printf("server: got connection from %s\n", client_inet_addr); // Create a child process if (!fork()) { close(sock_fd); handle_client(client_fd); exit(0); } close(client_fd); } } void *Seobeo_GetIP4OrIP6(struct sockaddr *sa) { if (sa->sa_family == AF_INET) { return &(((struct sockaddr_in*)sa)->sin_addr); } return &(((struct sockaddr_in6*)sa)->sin6_addr); }