#include #include #include #include #include #include #include #include #include "rt_api.h" int create_socket_fd(int port) { int server_fd; struct sockaddr_in address; int opt = 1; if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) { perror("socket failed"); exit(EXIT_FAILURE); } if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) { perror("setsockopt SO_REUSEADDR"); exit(EXIT_FAILURE); } #ifdef SO_REUSEPORT if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)) < 0) { perror("setsockopt SO_REUSEPORT"); exit(EXIT_FAILURE); } #endif memset(&address, 0, sizeof(address)); address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons(port); if (bind(server_fd, (struct sockaddr*)&address, sizeof(address)) < 0) { perror("bind failed"); exit(EXIT_FAILURE); } if (listen(server_fd, 3) < 0) { perror("listen"); exit(EXIT_FAILURE); } return server_fd; } int accept_socket(int fd) { int server_fd = fd; struct sockaddr_in client_addr; socklen_t addrlen = sizeof(client_addr); int new_socket = accept(server_fd, (struct sockaddr*)&client_addr, &addrlen); if (new_socket < 0) { perror("accept"); exit(EXIT_FAILURE); } return new_socket; } void write_string(int socket, TString data) { char* datastring = (char*) data->body; write(socket, datastring, strlen(datastring)); } void close_socket(int socket){ close(socket); } TString read_to_string(int socket, int bytes) { char* buffer = malloc(bytes + 1); int bytes_read = read(socket, buffer, bytes); if(bytes_read < 0) { bytes_read = 0; } TString string = tri_newString(bytes_read, bytes_read, buffer); free(buffer); return string; } int connect_socket(TString host, int port) { char* chost = (char*) host->body; struct addrinfo hints; struct addrinfo* res = NULL; char portstr[16]; snprintf(portstr, sizeof(portstr), "%d", port); memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; int gai = getaddrinfo(chost, portstr, &hints, &res); if (gai != 0) { perror("getaddrinfo"); return -1; } int sockfd = -1; for (struct addrinfo* p = res; p != NULL; p = p->ai_next) { sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol); if (sockfd < 0) continue; if (connect(sockfd, p->ai_addr, p->ai_addrlen) == 0) { break; // connected } close(sockfd); sockfd = -1; } freeaddrinfo(res); return sockfd; }