MPI_ERR_TRUNCATE: message truncated - mpi

I am getting MPI_ERR_TRUNCATE: message truncated error in the following code. This is a test code in which receiver process receives two messages from sender. In the first message it receives the value of the number of integers it receives in the second message. In the second message it receives those integers.
int main(int argc, char* argv[]){
MPI_Init(&argc,&argv);
int rank,nodes;
int i,j;
MPI_Status stat;
int size,wait;
int msgs = atoi(argv[1]);
MPI_Comm_size(MPI_COMM_WORLD, &nodes);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
MPI_Request req1;
MPI_Request*** req = (MPI_Request***)malloc(sizeof(MPI_Request**)*msgs);
for(i=0;i<msgs;i++){
req[i] = (MPI_Request**)malloc(sizeof(MPI_Request*)*(nodes-1));
for(j=0;j<nodes-1;j++){
req[i][j] = (MPI_Request*)malloc(sizeof(MPI_Request)*2);
}
}
if(rank==0){
int sent=0;
int data[10];
int pendingThreshold=100;
int sentThreshold=1000;
int completed=0;
size=2;
time_t t;
srand((unsigned) time(&t));
for(i=0;i<msgs;i++){
for(j=1;j<nodes;j++){
size=rand()%9+1;
printf("Sending size = %d at i=%d\n",size,i);
MPI_Isend(&size,1,MPI_INT,
j,0,MPI_COMM_WORLD,&(req[i][j-1][0]));
MPI_Isend (&data[0],size,
MPI_INT,j,1,MPI_COMM_WORLD,&(req[i][j-1][1]));
//Code for ensuring number of non blocking operations
//do not exceed a certain threshold
if(sent==sentThreshold){
while(sent>pendingThreshold){
int k=0;
wait=1;
while(wait){
MPI_Test(&req[completed][k][0], &wait, &stat);
wait = 1-wait;
if(!wait){
MPI_Test(&req[completed][k][1], &wait, &stat);
wait = 1-wait;
if(!wait){
k++;
if(k==nodes-1){
completed++;
sent--;
}
else{
wait=1;
}
}
}
}
}
}
}
sent++;
}
//Code for ensuring all non blocking operations are complete
wait = 1;
printf("Finished\n");
i=completed,j=0;
while(wait){
MPI_Test(&req[i][j][0], &wait, &stat);
wait = 1-wait;
if(!wait){
MPI_Test(&req[i][j][1], &wait, &stat);
wait = 1-wait;
if(!wait){
j++;
if(j==nodes-1){
j=0;
i++;
wait=1;
}
else{
wait=1;
}
if(i==msgs){
wait=0;
}
}
}
}
printf("Finished\n");
}
else{
int data[10];
MPI_Request req2;
for(i=0;i<msgs;i++){
MPI_Irecv (&size,1,MPI_INT,0,0,MPI_COMM_WORLD,&req1);
wait = 1;
while(wait){
MPI_Test(&req1, &wait, &stat);
wait = 1-wait;
}
wait = 1;
while(wait && i){
MPI_Test(&req2, &wait, &stat);
wait = 1-wait;
}
printf("Receiving size=%d at i=%d\n",size,i);
MPI_Irecv (&data[0],size,MPI_INT,0,1,MPI_COMM_WORLD,&req2);
size=0;
}
printf("Finished rank=%d\n",rank);
}
MPI_Barrier(MPI_COMM_WORLD);
MPI_Finalize();
}
This program receives MPI_ERR_TRUNCATE after multiple successful send-receives. The error occurs when receiver process receives a wrong size of integers to be received in its second message. For example:-
Sending size = 8 at i=1496
Sending size = 2 at i=1497
Sending size = 7 at i=1498
Sending size = 5 at i=1499
Sending size = 5 at i=1500
Sending size = 5 at i=1501
Sending size = 4 at i=1502
Sending size = 9 at i=1503
Sending size = 4 at i=1504
Receiving size=8 at i=1496
Receiving size=2 at i=1497
Receiving size=7 at i=1498
Receiving size=6 at i=1499
Receiving size=6 at i=1500
Receiving size=6 at i=1501
Receiving size=6 at i=1502
Receiving size=6 at i=1503
The error occurs at message number 1499 and after that it is receiving the same size for the further messages received. I had run my code for 100000 messages to be sent to the receiver process.
The following code uses MPI_Iprobe and works fine even for 1000000 messages.
int main(int argc, char* argv[]){
MPI_Init(&argc,&argv);
int rank,nodes;
int i,j;
MPI_Status stat;
int size,wait;
int msgs = atoi(argv[1]);
MPI_Comm_size(MPI_COMM_WORLD, &nodes);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
MPI_Request req1;
MPI_Request** req = (MPI_Request**)malloc(sizeof(MPI_Request*)*msgs);
for(i=0;i<msgs;i++){
req[i] = (MPI_Request*)malloc(sizeof(MPI_Request)*(nodes-1));
}
if(rank==0){
int sent=0;
int data[10];
int pendingThreshold=1000;
int sentThreshold=10000;
int completed=0;
size=2;
time_t t;
srand((unsigned) time(&t));
for(i=0;i<msgs;i++){
for(j=1;j<nodes;j++){
size=rand()%9+1;
printf("Sending size = %d at i=%d\n",size,i);
MPI_Isend (&data[0],size,
MPI_INT,j,1,MPI_COMM_WORLD,&(req[i][j-1]));
if(sent==sentThreshold){
while(sent>pendingThreshold){
int k=0;
wait=1;
while(wait){
MPI_Test(&req[completed][k], &wait, &stat);
wait = 1-wait;
if(!wait){
k++;
if(k==nodes-1){
completed++;
sent--;
}
else{
wait=1;
}
}
}
}
}
}
sent++;
}
wait = 1;
printf("Finished\n");
i=completed,j=0;
while(wait){
MPI_Test(&req[i][j], &wait, &stat);
wait = 1-wait;
if(!wait){
j++;
if(j==nodes-1){
j=0;
i++;
wait=1;
}
else{
wait=1;
}
if(i==msgs){
wait=0;
}
}
}
printf("Finished\n");
}
else{
int data[10];
MPI_Request req2;
for(i=0;i<msgs;i++){
wait = 1;
while(wait){
MPI_Iprobe(0,1,MPI_COMM_WORLD,&wait,&stat);
wait = 1-wait;
}
MPI_Get_count(&stat,MPI_INT,&size);
printf("Receiving size=%d at i=%d\n",size,i);
MPI_Irecv (&data[0],size,MPI_INT,0,1,MPI_COMM_WORLD,&req2);
size=0;
}
printf("Finished rank=%d\n",rank);
}
MPI_Barrier(MPI_COMM_WORLD);
MPI_Finalize();
}

Related

Move a BLDC motor using timer interrupt

I wanted to move my BLDC motor using a timer interrupt. Somehow, the motor would not spin at all. I want the motor to spin according to the RPM set in the code. I was wondering if you guys can pin point my mistakes. Here is the code:
#include <Wire.h> // Comes with Arduin
#define POSITIVE 1
int timerPin = 11;
int timer1_counter;
int prescaler;
// STATE CONDITION FOR MAIN LOOP
enum { enter_values, spin , finish } systemstate;
unsigned long previousMillis = 0;
// RPM MEASUREMENT
const int dataIN = 2; //IR sensor INPUT
unsigned long prevmillis; // To store time
unsigned long duration; // To store time difference
unsigned long lcdrefresh; // To store time for lcd to refresh
int rpm; // RPM value
boolean currentstate; // Current state of IR input scan
boolean prevstate; // State of IR sensor in previous scan
// DECLARE
int stage1speed , stage1time , stage2speed , stage2time , stage3speed , stage3time ;
void setup()
{
Serial.begin(9600);
systemstate = enter_values; // set up the starting state
pinMode(dataIN, INPUT);
prevmillis = 0;
prevstate = LOW;
pinMode (timerPin, OUTPUT);
//rmc timer interrupt
// initialize timer1
noInterrupts(); // disable all interrupts
TCCR1A = 0;
TCCR1B = 0;
// Set timer1_counter to the correct value for our interrupt interval
//timer1_counter = 64911; // preload timer 65536-16MHz/256/100Hz
//timer1_counter = 64286; // preload timer 65536-16MHz/256/50Hz
//timer1_counter = 34286; // preload timer 65536-16MHz/256/2Hz
timer1_counter = 65536 - F_CPU/256/2;
prescaler = 8;
TCNT1 = timer1_counter; // preload timer
TCCR1B |= (1 << CS11) | (0 << CS10); // prescaler
TIMSK1 |= (1 << TOIE1); // enable timer overflow interrupt
interrupts(); // enable all interrupts
}
ISR(TIMER1_OVF_vect) // interrupt service routine
{
static byte outp = 0;
TCNT1 = timer1_counter; // preload timer
digitalWrite(timerPin, outp);
outp = 1-outp;
}
//FUNCTION FOR KEY IN SPEED AND TIME
void enter_speed_time()
{
stage1speed = 4000;
stage1time = 10;
stage2speed = 6000;
stage2time = 10;
stage3speed = 8000;
stage3time = 10;
return;
}
// FUNCTION FOR RPM MEASUREMENT
void rpmMeasure()
{
static long last_update;
// RPM Measurement
currentstate = digitalRead(dataIN); // Read IR sensor state
if ( prevstate != currentstate) // If there is change in input
{
if ( currentstate == HIGH ) // If input only changes from LOW to HIGH
{
duration = ( micros() - prevmillis ); // Time difference between revolution in microsecond
rpm = (60000000 / duration); // rpm = (1/ time millis)*1000*1000*60;
prevmillis = micros(); // store time for next revolution calculation
}
}
prevstate = currentstate; // store this scan (prev scan) data for next scan
if (millis()-last_update > 1000)
{
Serial.print ("speed=");
Serial.println (rpm);
last_update = millis();
}
}
void set_speed (int speed)
{
Serial.print ("set speed=");
Serial.println (speed);
timer1_counter = 65536 - F_CPU/prescaler/speed*60/2;
//myservo.write(speed);
}
// FUNCTION FOR MOTOR SPINNING ACCORDING TO TIME AND SPEED
void motorspin()
{
unsigned long currentMillis = millis();
int idleValue = 0;
static enum { IDLE, STAGE1, STAGE2, STAGE3 } spinningstate;
switch (spinningstate) {
case IDLE:
set_speed(stage1speed);
previousMillis = currentMillis;
spinningstate = STAGE1;
break;
case STAGE1:
if (currentMillis - previousMillis >= stage1time * 1000) {
set_speed(stage2speed);
previousMillis = currentMillis;
spinningstate = STAGE2;
}
break;
case STAGE2:
if (currentMillis - previousMillis >= stage2time * 1000) {
set_speed(stage3speed);
previousMillis = currentMillis;
spinningstate = STAGE3;
}
break;
case STAGE3:
if (currentMillis - previousMillis >= stage3time * 1000) {
set_speed(idleValue);
spinningstate = IDLE;
}
break;
}
}
// MAIN LOOP
void loop()
{
switch (systemstate)
{
case enter_values:
enter_speed_time();
systemstate = spin;
break;
case spin:
rpmMeasure();
motorspin();
if (0) // haven't figure out yet
{
systemstate = finish;
}
break;
case finish:
systemstate = enter_values;
break;
}
}

Signal 11 (Segmentation fault) on MPI_Test

I am receiving segmentation fault on MPI_Test in the following code. The code involves a sender process and a receiver process. The sender process uses non-blocking send to send an integer value to the receiver process 1000000 times. This is just a test code. I am receiving a segmentation fault on MPI_Test in the sender process and am not able to figure out the reason why.
int main(int argc, char* argv[]){
MPI_Init(&argc,&argv);
int rank,nodes;
int i,j;
MPI_Status stat;
int size,wait;
int msgs = atoi(argv[1]);
MPI_Comm_size(MPI_COMM_WORLD, &nodes);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
MPI_Request req[msgs][nodes-1],req1;
if(rank==0){
size=2;
for(i=0;i<msgs;i++){
for(j=1;j<nodes;j++){
MPI_Isend(&size,1,MPI_INT,
j,0,MPI_COMM_WORLD,&(req[i][j-1]));
}
}
wait = 1;
i=0,j=0;
while(wait){
printf("at i=%d j=%d\n",i,j);
MPI_Test(&req[i][j], &wait, &stat);
wait = 1-wait;
if(!wait){
j++;
if(j==nodes-1){
j=0;
i++;
wait=1;
}
else{
wait=1;
}
if(i==msgs){
wait=0;
}
}
}
printf("Finished\n");
}
else{
for(i=0;i<msgs;i++){
MPI_Irecv (&size,1,MPI_INT,0,0,MPI_COMM_WORLD,&req1);
wait = 1;
while(wait){
MPI_Test(&req1, &wait, &stat);
wait = 1-wait;
}
if(size!=2){
printf("Received size=%d rank=%d\n",size,rank);
}
size=0;
}
printf("Finished rank=%d\n",rank);
}
MPI_Barrier(MPI_COMM_WORLD);
MPI_Finalize();
}
The output of the above program is:-
Finished
OK
OK
OK
OK
OK
after which it gives the segmentation fault
mpirun noticed that process rank 0 with PID 4576 exited on signal 11 (Segmentation fault).

How to use buffer to read and write using serial port in 8051 MCU

I am using keil c51 compiler. I transmit data from my pc to MCU using serial port it works best.
When I transmit data from my MCU to PC then also it works best.
But when I transmit data to MCU and then store it to buffer character pointer and again from that character pointer buffer I transmit return to PC then it does not work and give garbage values?
My code for both function as below.
#include <REG51.H>
#include "uart.c"
void delay_ms(unsigned int x) // delays x msec (at fosc=11.0592MHz)
{
unsigned char j=0;
while(x-- > 0)
{
for (j=0; j<125; j++){;}
}
}
sbit SW = P3^2;
sbit LED = P3^3;
bit x = 0;
void main ()
{
char *buf;
int len=0;
int len1 = 0;
uart_init();
while(1){
if(RI == 1){
UART_RxString(buf,&len);
buf -= (len-1) ;
x = 1;
}
if(x == 1 && SW == 0){
UART_TxString(buf,&len1);
x = 0;
}
}
}
And below are the functions.
1.
void UART_TxString(char *string_ptr, int *l)
{
int count = 0;
while(*string_ptr){
UART_TxChar(*string_ptr++);
count++;
}
*l = count;
}
void UART_RxString(char *string_ptr, int *l)
{
char ch;
int count = 0;
while(1)
{
ch=UART_RxChar(); //Reaceive a char
//UART_TxChar(ch); //Echo back the received char
count++;
if((ch=='\r') || (ch=='\n')) //read till enter key is pressed
{ //once enter key is pressed
*string_ptr=0; //null terminate the string
break; //and break the loop
}
*string_ptr=ch; //copy the char into string.
string_ptr++; //and increment the pointer
}
*l = count;
}

How to use and interpret MPI-IO Error codes?

#include <stdio.h>
#include <iostream>
#include <Windows.h>
#include <C:\Program Files\Microsoft MPI\Inc\mpi.h>
using namespace std;
#define BUFSIZE 128
int main (int argc, char *argv[])
{
int err;
int rank;
int size;
double start_time = 0.0;
double end_time;
MPI_Comm comm = MPI_COMM_WORLD;
MPI_File file;
char cbuf[BUFSIZE];
for(int i = 0; i < BUFSIZE; i++)
{
cbuf[i] = 'a' + i;
}
if(err = MPI_Init(&argc, &argv))
{
printf("%s \n", "Error! MPI is halted!");
MPI_Abort(comm, err);
}
MPI_Comm_size(comm, &size);
MPI_Comm_rank(comm, &rank);
if(rank == 0)
{
start_time = MPI_Wtime();
}
err = MPI_File_open(comm, "testfile", MPI_MODE_CREATE | MPI_MODE_RDWR, MPI_INFO_NULL, &file);
if(err != MPI_SUCCESS)
{
printf("Error %d! Can't open the file!\n", err);
MPI_Abort(comm, err);
return EXIT_FAILURE;
}
err = MPI_File_set_view(file, (MPI_Offset) (rank * BUFSIZE * sizeof(char)), MPI_CHAR, MPI_CHAR, "native", MPI_INFO_NULL);
if(err != MPI_SUCCESS)
{
printf("%s \n", "Error! Can't set the view!");
MPI_Abort(comm, err);
return EXIT_FAILURE;
}
err = MPI_File_write(file, cbuf, BUFSIZE, MPI_CHAR, MPI_STATUSES_IGNORE);
if(err != MPI_SUCCESS)
{
printf("%s \n", "Error! Problems with writing!");
MPI_Abort(comm, err);
return EXIT_FAILURE;
}
MPI_File_close(&file);
if(rank == 0)
{
end_time = MPI_Wtime();
printf("Time elapsed : %f seconds", (end_time - start_time) * 1000);
}
MPI_Finalize();
return EXIT_SUCCESS;
}
I'm trying to write some symbols to a file with MPI. When I do that, I get an errorcode of 288 and the file can't be opened. I used command line: mpiexec -n 10 myapp.exe. I was searching for the errorcode but didn't find anything at all.
Go one step further. Your error code doesn't mean anything by itself. But, you can feed that code to MPI_Error_string and get something more human readable. I have this function in every MPI-IO code I write:
static void handle_error(int errcode, char *str)
{
char msg[MPI_MAX_ERROR_STRING];
int resultlen;
MPI_Error_string(errcode, msg, &resultlen);
fprintf(stderr, "%s: %s\n", str, msg);
MPI_Abort(MPI_COMM_WORLD, 1);
}
And then define this macro:
#define MPI_CHECK(fn) { int errcode; errcode = (fn);\
if (errcode != MPI_SUCCESS) handle_error (errcode, #fn ); }
So I can call routines like this:
CHECK(MPI_File_open(comm, "testfile",
MPI_MODE_CREATE | MPI_MODE_RDWR, MPI_INFO_NULL, &file) );

Why recv() in winsock client cannot get any data once httpRetransmition happens?

I am trying to record the time between 'http request' package and 'http response' package.
I write an socket client using winsock. The code is below
if (send(sock, request.c_str(), request.length(), 0) != request.length())
die_with_error("send() sent a different number of bytes than expected");
// Record the time of httpRequestSent
::QueryPerformanceCounter(&httpRequestSent);
::QueryPerformanceFrequency(&frequency);
//get response
response = "";
resp_leng= BUFFERSIZE;
http_leng= 381;
while(resp_leng==BUFFERSIZE||http_leng>0)
{
resp_leng= recv(sock, (char*)&buffer, BUFFERSIZE, 0);
http_leng= http_leng - resp_leng;
if (resp_leng>0)
response+= string(buffer).substr(0,resp_leng);
//note: download lag is not handled in this code
}
::QueryPerformanceCounter(&httpResponseGot);
//display response
cout << response << endl;
// Display the HTTP duration
httpDuration = (double)(httpResponseGot.QuadPart - httpRequestSent.QuadPart) / (double)frequency.QuadPart;
printf("The HTTP duration is %lf\n", httpDuration);
The code works nicely except one situation: HTTP Retransmition. I used wireshark to monitor packages and found out once there is a retransmition the code seems block on recv(), but cannot get any data from the socket buffer. I wonder why would this happen. Could somebody explain the reasons?
Any help will be appreciated.
Here is a second answer with more dynamic buffer handling and more error checking:
void send_data(SOCKET sock, void *data, unsigned int data_len)
{
unsigned char *ptr = (unsigned char*) data;
while (data_len > 0)
{
int num_to_send = (int) std::min(1024*1024, data_len);
int num_sent = send(sock, ptr, num_to_send, 0);
if (num_sent < 0)
{
if ((num_sent == SOCKET_ERROR) && (WSAGetLastError() == WSAEWOULDBLOCK))
continue;
die_with_error("send() failed");
}
if (num_sent == 0)
die_with_error("socket disconnected");
ptr += num_sent;
data_len -= num_sent;
}
}
unsigned int recv_data(SOCKET sock, void *data, unsigned int data_len, bool error_on_disconnect = true)
{
unsigned char *ptr = (unsigned char*) data;
unsigned int total = 0;
while (data_len > 0)
{
int num_to_recv = (int) std::min(1024*1024, data_len);
int num_recvd = recv(sock, ptr, num_to_recv, 0);
if (num_recvd < 0)
{
if ((num_recvd == SOCKET_ERROR) && (WSAGetLastError() == WSAEWOULDBLOCK))
continue;
die_with_error("recv() failed");
}
if (num_recvd == 0)
{
if (error_on_disconnect)
die_with_error("socket disconnected");
break;
}
ptr += num_recvd;
datalen -= num_recvd;
total += num_recvd;
}
while (true);
return total;
}
std::string recv_line(SOCKET sock)
{
std::string line;
char c;
do
{
recv_data(sock, &c, 1);
if (c == '\r')
{
recv_data(sock, &c, 1);
if (c == '\n')
break;
line += '\r';
}
else if (c == '\n')
break;
line += c;
}
return line;
}
void recv_headers(SOCKET sock, std::vector<std::string> *hdrs)
{
do
{
std::string line = recv_line(sock);
if (line.length() == 0)
return;
if (hdrs)
hdrs->push_back(line);
}
while (true);
}
unsigned int recv_chunk_size(SOCKET sock)
{
std::string line = recv_line(sock);
size_t pos = line.find(";");
if (pos != std::string::npos)
line.erase(pos);
char *endptr;
unsigned int value = strtoul(line.c_str(), &endptr, 16);
if (*endptr != '\0')
die_with_error("bad Chunk Size received");
return value;
}
std::string find_header(const std::vector<std::string> &hrds, const std::string &hdr_name)
{
std::string value;
for(size_t i = 0; i < hdrs.size(); ++i)
{
const std::string hdr = hdrs[i];
size_t pos = hdr.find(":");
if (pos != std::string::npos)
{
if (hdr.compare(0, pos-1, name) == 0)
{
pos = hdr.find_first_not_of(" ", pos+1);
if (pos != std::string::npos)
return hdr.substr(pos);
break;
}
}
}
return "";
}
{
// send request ...
std::string request = ...;
send_data(sock, request.c_str(), request.length());
// Record the time of httpRequestSent
::QueryPerformanceCounter(&httpRequestSent);
::QueryPerformanceFrequency(&frequency);
// get response ...
std::vector<std::string> resp_headers;
std::vector<unsigned char> resp_data;
recv_headers(sock, &resp_headers);
std::string transfer_encoding = find_header(resp_headers, "Transfer-Encoding");
if (transfer_encoding.find("chunked") != std::string::npos)
{
unsigned int chunk_len = recv_chunk_size(sock);
while (chunk_len != 0)
{
size_t offset = resp_data.size();
resp_data.resize(offset + chunk_len);
recv_data(sock, &resp_data[offset], chunk_len);
recv_line(sock);
chunk_len = recv_chunk_size(sock);
}
recv_headers(sock, NULL);
}
else
{
std::string content_length = find_header(resp_headers, "Content-Length");
if (content_length.length() != 0)
{
char *endptr;
unsigned int content_length_value = strtoul(content_length.c_str(), &endptr, 10);
if (*endptr != '\0')
die_with_error("bad Content-Length value received");
if (content_length_value > 0)
{
resp_data.resize(content_length_value);
recv_data(sock, &resp_data[0], content_length_value);
}
}
else
{
unsigned char buffer[BUFFERSIZE];
do
{
unsigned int buffer_len = recv_data(sock, buffer, BUFFERSIZE, false);
if (buffer_len == 0)
break;
size_t offset = resp_data.size();
resp_data.resize(offset + buffer_len);
memcpy(&resp_data[offset], buffer, buffer_len);
}
while (true)
}
}
::QueryPerformanceCounter(&httpResponseGot);
// process resp_data as needed
// may be compressed, encoded, etc...
// Display the HTTP duration
httpDuration = (double)(httpResponseGot.QuadPart - httpRequestSent.QuadPart) / (double)frequency.QuadPart;
printf("The HTTP duration is %lf\n", httpDuration);
}
You are not doing adequate error checking on the calls to send() and recv(). Try something like this instead:
char *req_ptr = request.c_str();
int req_leng = request.length();
int req_index = 0;
do
{
int req_sent = send(sock, req_ptr, req_leng, 0);
if (req_sent < 1)
{
if ((req_sent == SOCKET_ERROR) && (WSAGetLastError() == WSAEWOULDBLOCK))
continue;
die_with_error("send() failed");
}
req_ptr += req_sent;
req_leng -= req_sent;
}
while (req_leng > 0);
// Record the time of httpRequestSent
::QueryPerformanceCounter(&httpRequestSent);
::QueryPerformanceFrequency(&frequency);
//get response
std::string response;
int resp_leng = BUFFERSIZE;
int http_leng = -1;
bool http_leng_needed = true;
do
{
if (http_leng_needed)
{
std::string::size_type pos = response.find("\r\n\r\n");
if (pos != std::string::npos)
{
std::string resp_hdrs = response.substr(0, pos);
// look for a "Content-Length" header to see
// if the server sends who many bytes are
// being sent after the headers. Note that
// the server may use "Transfer-Encoding: chunked"
// instead, which has no "Content-Length" header...
//
// I will leave this as an excercise for you to figure out...
http_leng = ...;
// in case body bytes have already been received...
http_leng -= (response.length() - (pos+4));
http_leng_needed = false;
}
}
if (http_leng_needed)
resp_leng = BUFFERSIZE;
else
resp_leng = min(http_leng, BUFFERSIZE);
if (resp_leng == 0)
break;
resp_leng = recv(sock, buffer, resp_leng, 0);
if (resp_leng < 1)
{
if ((resp_leng == SOCKET_ERROR) && (WSAGetLastError() == WSAEWOULDBLOCK))
continue;
die_with_error("send() failed");
}
response += string(buffer, resp_leng);
if (!http_leng_needed)
http_leng -= resp_leng;
}
while ((http_leng_needed) || (http_leng > 0));
::QueryPerformanceCounter(&httpResponseGot);
//display response
cout << response << endl;
// Display the HTTP duration
httpDuration = (double)(httpResponseGot.QuadPart - httpRequestSent.QuadPart) / (double)frequency.QuadPart;
printf("The HTTP duration is %lf\n", httpDuration);
With this said, the "correct" way to handle HTTP in general is to read the inbound data line by line, rather than buffer by buffer, until you encounter the end of the response headers, then you can read the rest of the data buffer by buffer based on the data length indicated by the headers.

Resources