Changed 'recvAll' return type from std::string to char pointer, and created a non-blocking version of the function

This commit is contained in:
2024-02-28 00:04:43 -05:00
parent ba667d020d
commit a37ec79f09
2 changed files with 47 additions and 14 deletions

View File

@@ -34,8 +34,14 @@ public:
/* Method to send data in 'to_send' through the 'other_socket' socket */ /* Method to send data in 'to_send' through the 'other_socket' socket */
void sendAll(std::string to_send); 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 */ /* 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 */ /* Returns socket identifier */
int getSockFD(); int getSockFD();

View File

@@ -68,26 +68,35 @@ void Sock::sendAll(std::string to_send) {
return; 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.
'recv' method is called until all the data has been read. For UDP, the 'recvfrom' It then calls the method above, passing that string as a parameter. */
method is only called once. void Sock::sendAll(char* buffer, int size) {
This function also needs more testing for TCP. */ std::string to_send = std::string(buffer, size);
sendAll(to_send);
}
std::string Sock::recvAll() { /* Receives data from 'other_socket' into a char *, and returns that char *. For TCP, the
int num_bytes_received; 'recv' method is called until all the data has been read. For UDP, the 'recvfrom'
std::string string = std::string(); method is only called once. The 'select' function is used to poll data for UDP
This function also needs more testing for TCP. */
char* Sock::recvAll() {
int num_bytes_received = 0;
int total_bytes_received = 0;
char* buffer = (char *)malloc(100); char* buffer = (char *)malloc(100);
bool has_been_read = false; bool has_been_read = false;
if (this->protocol == ES_UDP) { 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 */ /* Null-terminate the string */
*(buffer + num_bytes_received) = '\0'; *(buffer + num_bytes_received) = '\0';
string.append(std::string(buffer)); return buffer;
} }
/* For TCP sockets */ /* For TCP sockets */
else { 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 ((errno == EAGAIN || errno == EWOULDBLOCK)) {
if (has_been_read) { if (has_been_read) {
@@ -100,13 +109,31 @@ std::string Sock::recvAll() {
if (num_bytes_received < 0) { if (num_bytes_received < 0) {
throw errno * -1; throw errno * -1;
} }
string.append(std::string(buffer)); total_bytes_received += num_bytes_received;
has_been_read = true; 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() { int Sock::getSockFD() {