Added comments to explain functions, and added UDP handling
This commit is contained in:
70
sock.cpp
70
sock.cpp
@@ -4,10 +4,19 @@
|
||||
#include "includes/exception_consts.hpp"
|
||||
#include "includes/easysock.hpp"
|
||||
|
||||
/* Function to create socket. This function doesn't actually create a socket
|
||||
(and isn't meant to be called directly). Instead, the client and server classes
|
||||
extend this function, and create the appropriate sockets. */
|
||||
|
||||
void Sock::create_socket() {
|
||||
dest = (struct sockaddr *)malloc(sizeof(struct sockaddr));
|
||||
addrlen = sizeof(*dest);
|
||||
}
|
||||
|
||||
/* Constructor - This function initializes the object attributes with the given
|
||||
parameters. It throws an exception if an IPv4 address was given, but the type
|
||||
given is IPv6 (or the other way around). */
|
||||
|
||||
Sock::Sock(int ip_ver, char protocol, const char* address, int port) {
|
||||
/* Error checking */
|
||||
if (ip_ver != 4 && ip_ver != 6) {
|
||||
@@ -29,33 +38,70 @@ Sock::Sock(int ip_ver, char protocol, const char* address, int port) {
|
||||
if ((check_ip_ver(address) != 6 && ip_ver == 6) || (check_ip_ver(address) != 4 && ip_ver == 4)) {
|
||||
throw std::invalid_argument("Invalid IP address for given type.");
|
||||
}
|
||||
|
||||
try {
|
||||
create_socket();
|
||||
} catch (int e) {
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void Sock::sendAll(std::string to_send) {
|
||||
/* This method sends the given data, through the given socket. Client and server
|
||||
classes extend this method, by calling it with different parameters.
|
||||
This function needs more testing for TCP, as it focuses on UDP right now. */
|
||||
|
||||
void Sock::sendAll(std::string to_send, int dest_sock) {
|
||||
int str_length = to_send.length();
|
||||
int num_bytes_sent = 0; /* Number of bytes sent in one call to send */
|
||||
int total_bytes_sent = 0; /* Total number of bytes sent */
|
||||
|
||||
while (total_bytes_sent < str_length) {
|
||||
num_bytes_sent = send(this->getSockFD(), to_send.substr(total_bytes_sent).data(), str_length - total_bytes_sent, 0);
|
||||
total_bytes_sent += num_bytes_sent;
|
||||
/* For UDP sockets */
|
||||
if (this->protocol == 'U') {
|
||||
sendto(this->sock_fd, to_send.data(), str_length, 0, dest, addrlen);
|
||||
}
|
||||
/* For TCP sockets */
|
||||
else {
|
||||
while (total_bytes_sent < str_length) {
|
||||
num_bytes_sent = send(dest_sock, to_send.substr(total_bytes_sent).data(), str_length - total_bytes_sent, 0);
|
||||
if (num_bytes_sent < 0) {
|
||||
throw errno * -1;
|
||||
}
|
||||
total_bytes_sent += num_bytes_sent;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
std::string Sock::recvAll() {
|
||||
/* Receives data from given socket into a string, and returns that string. For TCP, the
|
||||
'recv' method is called until all the data has been read. For UDP, the 'recvfrom'
|
||||
method is only called once.
|
||||
This function also needs more testing for TCP. */
|
||||
|
||||
std::string Sock::recvAll(int from_sock) {
|
||||
int num_bytes_received;
|
||||
std::string string = std::string();
|
||||
char* buffer = (char *)malloc(100);
|
||||
while (recv(this->getSockFD(), buffer, 100, 0) != 0) {
|
||||
bool has_been_read = false;
|
||||
|
||||
if (this->protocol == 'U') {
|
||||
recvfrom(this->sock_fd, buffer, 100, 0, dest, &addrlen);
|
||||
string.append(std::string(buffer));
|
||||
}
|
||||
/* For TCP sockets */
|
||||
else {
|
||||
while ((num_bytes_received = recv(from_sock, buffer, 100, 0)) != 0) {
|
||||
|
||||
if ((errno == EAGAIN || errno == EWOULDBLOCK)) {
|
||||
if (has_been_read) {
|
||||
break;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (num_bytes_received < 0) {
|
||||
throw errno * -1;
|
||||
}
|
||||
string.append(std::string(buffer));
|
||||
has_been_read = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return string;
|
||||
}
|
||||
|
Reference in New Issue
Block a user