Fixed - when playing around with the code, I saw that some data at the end was repeating, and I realised it was because it was trying to fill up the buffer for the last chunk of data even though the remaining data wasn't large enough, so it re-read from the start of that chunk to fill up the buffer, and duplicated some data.
This version reads the data in chunks but only tries to assign what's available, not always BUFFER_SIZE.
int nDataLength;
while ((nDataLength = recv(sock, (char*)&buffer, BUFFER_SIZE, 0)) > 0)
{
for(int x = 0; x < nDataLength; x++)
{
response += buffer[x];
}
}