Overloaded Socket::Connection::Send with new versions and now requires arguments to be passed by reference. Also fixed a ::close bug and hugely improved performance.
This commit is contained in:
parent
a0bcc4779e
commit
6d3598eea0
2 changed files with 80 additions and 12 deletions
|
@ -58,16 +58,22 @@ Socket::Connection::Connection(){
|
||||||
Blocking = false;
|
Blocking = false;
|
||||||
}//Socket::Connection basic constructor
|
}//Socket::Connection basic constructor
|
||||||
|
|
||||||
|
/// Internally used call to make an file descriptor blocking or not.
|
||||||
/// Set this socket to be blocking (true) or nonblocking (false).
|
void setFDBlocking(int FD, bool blocking){
|
||||||
void Socket::Connection::setBlocking(bool blocking){
|
int flags = fcntl(FD, F_GETFL, 0);
|
||||||
int flags = fcntl(sock, F_GETFL, 0);
|
|
||||||
if (!blocking){
|
if (!blocking){
|
||||||
flags |= O_NONBLOCK;
|
flags |= O_NONBLOCK;
|
||||||
}else{
|
}else{
|
||||||
flags &= !O_NONBLOCK;
|
flags &= !O_NONBLOCK;
|
||||||
}
|
}
|
||||||
fcntl(sock, F_SETFL, flags);
|
fcntl(FD, F_SETFL, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set this socket to be blocking (true) or nonblocking (false).
|
||||||
|
void Socket::Connection::setBlocking(bool blocking){
|
||||||
|
if (sock >=0){setFDBlocking(sock, blocking);}
|
||||||
|
if (pipes[0] >=0){setFDBlocking(pipes[0], blocking);}
|
||||||
|
if (pipes[1] >=0){setFDBlocking(pipes[1], blocking);}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Close connection. The internal socket is closed and then set to -1.
|
/// Close connection. The internal socket is closed and then set to -1.
|
||||||
|
@ -79,15 +85,18 @@ void Socket::Connection::close(){
|
||||||
#endif
|
#endif
|
||||||
if (sock != -1){
|
if (sock != -1){
|
||||||
shutdown(sock, SHUT_RDWR);
|
shutdown(sock, SHUT_RDWR);
|
||||||
::close(sock);
|
errno = EINTR;
|
||||||
|
while (::close(sock) != 0 && errno == EINTR){}
|
||||||
sock = -1;
|
sock = -1;
|
||||||
}
|
}
|
||||||
if (pipes[0] != -1){
|
if (pipes[0] != -1){
|
||||||
::close(pipes[0]);
|
errno = EINTR;
|
||||||
|
while (::close(pipes[0]) != 0 && errno == EINTR){}
|
||||||
pipes[0] = -1;
|
pipes[0] = -1;
|
||||||
}
|
}
|
||||||
if (pipes[1] != -1){
|
if (pipes[1] != -1){
|
||||||
::close(pipes[1]);
|
errno = EINTR;
|
||||||
|
while (::close(pipes[1]) != 0 && errno == EINTR){}
|
||||||
pipes[1] = -1;
|
pipes[1] = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -237,8 +246,64 @@ std::string & Socket::Connection::Received(){
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Appends data to the upbuffer.
|
/// Appends data to the upbuffer.
|
||||||
void Socket::Connection::Send(std::string data){
|
/// This will attempt to send the upbuffer (if non-empty) first.
|
||||||
upbuffer.append(data);
|
/// If the upbuffer is empty before or after this attempt, it will attempt to send
|
||||||
|
/// the data right away. Any data that could not be send will be put into the upbuffer.
|
||||||
|
/// This means this function is blocking if the socket is, but nonblocking otherwise.
|
||||||
|
void Socket::Connection::Send(std::string & data){
|
||||||
|
if (upbuffer.size() > 0){
|
||||||
|
iwrite(upbuffer);
|
||||||
|
if (upbuffer.size() > 0){
|
||||||
|
upbuffer.append(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (upbuffer.size() == 0){
|
||||||
|
int i = iwrite(data.c_str(), data.size());
|
||||||
|
if (i < data.size()){
|
||||||
|
upbuffer.append(data, i, data.size() - i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Appends data to the upbuffer.
|
||||||
|
/// This will attempt to send the upbuffer (if non-empty) first.
|
||||||
|
/// If the upbuffer is empty before or after this attempt, it will attempt to send
|
||||||
|
/// the data right away. Any data that could not be send will be put into the upbuffer.
|
||||||
|
/// This means this function is blocking if the socket is, but nonblocking otherwise.
|
||||||
|
void Socket::Connection::Send(const char * data){
|
||||||
|
int len = strlen(data);
|
||||||
|
if (upbuffer.size() > 0){
|
||||||
|
iwrite(upbuffer);
|
||||||
|
if (upbuffer.size() > 0){
|
||||||
|
upbuffer.append(data, (size_t)len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (upbuffer.size() == 0){
|
||||||
|
int i = iwrite(data, len);
|
||||||
|
if (i < len){
|
||||||
|
upbuffer.append(data + i, (size_t)(len - i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Appends data to the upbuffer.
|
||||||
|
/// This will attempt to send the upbuffer (if non-empty) first.
|
||||||
|
/// If the upbuffer is empty before or after this attempt, it will attempt to send
|
||||||
|
/// the data right away. Any data that could not be send will be put into the upbuffer.
|
||||||
|
/// This means this function is blocking if the socket is, but nonblocking otherwise.
|
||||||
|
void Socket::Connection::Send(const char * data, size_t len){
|
||||||
|
if (upbuffer.size() > 0){
|
||||||
|
iwrite(upbuffer);
|
||||||
|
if (upbuffer.size() > 0){
|
||||||
|
upbuffer.append(data, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (upbuffer.size() == 0){
|
||||||
|
int i = iwrite(data, len);
|
||||||
|
if (i < len){
|
||||||
|
upbuffer.append(data + i, len - i);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Incremental write call. This function tries to write len bytes to the socket from the buffer,
|
/// Incremental write call. This function tries to write len bytes to the socket from the buffer,
|
||||||
|
@ -593,7 +658,8 @@ void Socket::Server::close(){
|
||||||
fprintf(stderr, "ServerSocket closed.\n");
|
fprintf(stderr, "ServerSocket closed.\n");
|
||||||
#endif
|
#endif
|
||||||
shutdown(sock, SHUT_RDWR);
|
shutdown(sock, SHUT_RDWR);
|
||||||
::close(sock);
|
errno = EINTR;
|
||||||
|
while (::close(sock) != 0 && errno == EINTR){}
|
||||||
sock = -1;
|
sock = -1;
|
||||||
}
|
}
|
||||||
}//Socket::Server::close
|
}//Socket::Server::close
|
||||||
|
|
|
@ -56,7 +56,9 @@ namespace Socket{
|
||||||
bool spool(); ///< Updates the downbuffer and upbuffer internal variables.
|
bool spool(); ///< Updates the downbuffer and upbuffer internal variables.
|
||||||
bool flush(); ///< Updates the downbuffer and upbuffer internal variables until upbuffer is empty.
|
bool flush(); ///< Updates the downbuffer and upbuffer internal variables until upbuffer is empty.
|
||||||
std::string & Received(); ///< Returns a reference to the download buffer.
|
std::string & Received(); ///< Returns a reference to the download buffer.
|
||||||
void Send(std::string data); ///< Appends data to the upbuffer.
|
void Send(std::string & data); ///< Appends data to the upbuffer.
|
||||||
|
void Send(const char * data); ///< Appends data to the upbuffer.
|
||||||
|
void Send(const char * data, size_t len); ///< Appends data to the upbuffer.
|
||||||
//stats related methods
|
//stats related methods
|
||||||
unsigned int dataUp(); ///< Returns total amount of bytes sent.
|
unsigned int dataUp(); ///< Returns total amount of bytes sent.
|
||||||
unsigned int dataDown(); ///< Returns total amount of bytes received.
|
unsigned int dataDown(); ///< Returns total amount of bytes received.
|
||||||
|
|
Loading…
Add table
Reference in a new issue