Assuming this is a SOCK_STREAM socket, the important thing to be aware of is that the underlying TCP protocol does not maintain any segment boundaries. That is, when you call send() multiple times, all of the data you sent may very easily be returned by a single recv() call at the other end. Or, the data sent in one send() call may be returned in multiple recv()s at the other end, e.g. if some packets got delayed due to network congestion. This is fundamental to the design of TCP, and your application must be designed accordingly.
Also, as noted by Mehrdad, the recv() call returns the number of bytes that were read off the wire. Anything after that point in the buffer is garbage, and the data is not zero-terminated.
A SOCK_DGRAM socket uses UDP underneath, which is entirely packet-oriented, as opposed to stream-oriented like TCP. However, UDP does not guarantee reliability (the U stands for Unreliable), so you have to handle lost, duplicated, out-of-order etc. packets yourself. This is a lot harder than stream-oriented I/O.