1. Вы полностью игнорируете размер прочитанных данных, которые возвращает recv.
recv - не обязуется прочитать то количество данных, которое вы ей передаете как размер буфера. Она возвращает реально прочитанное количество данных.
2. При получении информации по сети не гарантируется, что отправляемые данные придут все за один раз (и так же прочитаются recv), они могут фрагментироваться, задерживаться, сцепляться со следующими пакетами и т.п.
Разбор полученных данных ложится на принимающую сторону.
3. В данных, возвращаемых recv, обычно нет нулевого символа в конце строк. Т.е., если вы ждете строку, то для дальнейшей работы с полученными данными как со строкой вы должны сами обозначить конец строки - принудительно проставить нулевой символ. Для этого в приемном буфере у вас должно быть предусмотрено место для нулевого символа при любом размере полученных данных.
Без этого большинство функций, работающих со строками будут давать не правильный результат.
4. Если вы ждете строго определенный размер данных, то вы должны в коде предусмотреть чтение сокета до тех пор, пока не вычитаете нужное количество данных. При этом вызовов recv может быть несколько (см.п.1, 2).
5. Если вы ждете в прочитанных данных какого-то завершающего символа (конца строки как в FTP), то вы должны самостоятельно проверять наличие этого символа(ов) - recv за вас это не сделает. Если в текущих полученных данных от recv нет конца строки - это не значит, что произошла ошибка. Это значит, что прочитаны не все данные и нужно еще их дочитывать.