The short answer to your question is that I would go reading one byte at a time. Unfortunately, this is one of those cases where in both cases there are pros and cons.
To use a buffer is the fact that an implementation may be more efficient in terms of network I / O. Against using a buffer, I believe that the code will be inherently more complex than the single-byte version. Thus, its effectiveness against complexity is minimized. The good news is that you can first implement a simple solution, profile the result and “zoom in” to a buffered approach if testing shows that it is worth it.
Also, just to be noted as a thought experiment, I wrote some pseudo-code for a loop that does the buffered reads of the http packets included below. The complexity of implementing buffered reads doesn't seem bad. Please note, however, that I did not pay much attention to error handling or checked if this would even work. However, it should avoid excessive “double processing” of the data, which is important because it reduces the efficiency that was the goal of this approach.
#define CHUNK_SIZE 1024 nextHttpBytesRead = 0; nextHttp = NULL; while (1) { size_t httpBytesRead = nextHttpBytesRead; size_t thisHttpSize; char *http = nextHttp; char *temp; char *httpTerminator; do { temp = realloc(httpBytesRead + CHUNK_SIZE); if (NULL == temp) ... http = temp; httpBytesRead += read(httpSocket, http + httpBytesRead, CHUNK_SIZE); httpTerminator = strstr(http, "\r\n\r\n"); }while (NULL == httpTerminator) thisHttpSize = ((int)httpTerminator - (int)http + 4; // Include terminator nextHttpBytesRead = httpBytesRead - thisHttpSize; // Adding CHUNK_SIZE here means that the first realloc won't have to do any work nextHttp = malloc(nextHttpBytesRead + CHUNK_SIZE); memcpy(nextHttp, http + thisHttpSize, nextHttpSize); http[thisHttpSize] = '\0'; processHttp(http); }
torak source share