diff --git a/includes/sock.hpp b/includes/sock.hpp index 9cd6e94..74ca542 100644 --- a/includes/sock.hpp +++ b/includes/sock.hpp @@ -33,9 +33,15 @@ public: /* Method to send data in 'to_send' through the 'other_socket' socket */ void sendAll(std::string to_send); + + /* Same as method above, with buffer and buffer size */ + void sendAll(char* buffer, int size); /* Method to receive data sent to the 'other_socket' socket */ - std::string recvAll(); + char* recvAll(); + + /* Non-blocking receive method - calls the method above after polling for data */ + char* recvAllNB(); /* Returns socket identifier */ int getSockFD(); diff --git a/sock.cpp b/sock.cpp index 2d190d7..e6d4efc 100644 --- a/sock.cpp +++ b/sock.cpp @@ -64,30 +64,39 @@ void Sock::sendAll(std::string to_send) { total_bytes_sent += num_bytes_sent; } } - + return; } -/* Receives data from 'other_socket' into a string, and returns that string. For TCP, the +/* This method receives a (char *) and a size, and creates a std::string with it. +It then calls the method above, passing that string as a parameter. */ +void Sock::sendAll(char* buffer, int size) { + std::string to_send = std::string(buffer, size); + sendAll(to_send); +} + +/* Receives data from 'other_socket' into a char *, and returns that char *. For TCP, the 'recv' method is called until all the data has been read. For UDP, the 'recvfrom' -method is only called once. +method is only called once. The 'select' function is used to poll data for UDP This function also needs more testing for TCP. */ - -std::string Sock::recvAll() { - int num_bytes_received; - std::string string = std::string(); +char* Sock::recvAll() { + int num_bytes_received = 0; + int total_bytes_received = 0; char* buffer = (char *)malloc(100); bool has_been_read = false; if (this->protocol == ES_UDP) { - num_bytes_received = recvfrom(this->sock_fd, buffer, 100, 0, dest, &addrlen); + num_bytes_received = recvfrom(this->sock_fd, buffer, 99, 0, dest, &addrlen); + if (num_bytes_received == 0) { + return NULL; + } /* Null-terminate the string */ *(buffer + num_bytes_received) = '\0'; - string.append(std::string(buffer)); + return buffer; } /* For TCP sockets */ else { - while ((num_bytes_received = recv(this->other_socket, buffer, 100, 0)) != 0) { + while ((num_bytes_received = recv(this->other_socket, buffer + total_bytes_received, 100 - total_bytes_received, 0)) != 0) { if ((errno == EAGAIN || errno == EWOULDBLOCK)) { if (has_been_read) { @@ -100,13 +109,31 @@ std::string Sock::recvAll() { if (num_bytes_received < 0) { throw errno * -1; } - string.append(std::string(buffer)); + total_bytes_received += num_bytes_received; has_been_read = true; } } - return string; + return buffer; +} + +/* Non-blocking recv call - Uses 'select' to poll for data from the FD. */ +char* Sock::recvAllNB() { + struct timeval tv; + fd_set readfs; + tv.tv_sec = 0; // Set to 0 to poll instead of wait + tv.tv_usec = 0; // Set to 0 to poll instead of wait + FD_ZERO(&readfs); + FD_SET(this->sock_fd, &readfs); + + select(this->sock_fd + 1, &readfs, NULL, NULL, &tv); + + if (FD_ISSET(this->sock_fd, &readfs)) { + return Sock::recvAll(); + } else { + return NULL; + } } int Sock::getSockFD() {