I'll purely suggest some changes to code structure, but as @user58697 states, you should carefully check the man page to recv and handle each and every error condition.
The first thing to do is to break up the code a bit. Secondly, a lot of people prefer a single return point. The record terminator should be a defined constant.
Capture the concepts of a valid read and the desire to discard buffered data in methods.
Probably matching the record terminator should also really be broken out into a method.
Also recv returns ssize_t.
class Socket
{
public:
std::string RecvData();
static const char recordTerminator = '\n';
private:
int s_;
bool validRead(ssize_t recvCode);
bool discardBuffer(ssize_t recvCode);
};
bool Socket::validRead(ssize_t recvCode)
{
return (recvCode != INVALID_SOCKET && recvCode != SOCKET_ERROR);
}
bool Socket::discardBuffer(ssize_t recvCode)
{
return (recvCode == INVALID_SOCKET ||
(recvCode == SOCKET_ERROR && errno != EAGAIN));
}
std::string Socket::RecvData()
{
std::string stringRead;
bool readMore = true;
while(readMore)
{
char singleChar = 0;
ssize_t recvInt = recv(s_, &singleChar, 1, 0);
readMore = validRead(recvInt);
if (readMore)
stringRead += singleChar;
else if (discardBuffer(recvInt))
stringRead = "";
if (readMore && (singleChar == recordTerminator))
readMore = false;
}
return stringRead;
}