Click here to Skip to main content
16,017,954 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
recently , I meet a question about the function recv of socket programming, let me introduce the background of the question ,
now I have a client and server in different pc , the client is linux OS without any 3th network libray, such ACE , curl ... and the server is Window OS - and I have deployed the http server - Apache , in my project , I will send http post request from socket programming to server which is a php website timely (about 1 time 2 seconds), and the post data is encapluted with Json format , that is the http Content-Type:application/json, but when I send the request , then I recv the response with Json format from server (in fact the response data is not big < 5*1024), but in the next , very slowly , about more than 10 seconds ,then I can get the response wholly , sometimes can not the any response Json , I suppose the reason is bacause the unfit buf length , I tried 1024 , 2048 , 512 ... , and the result is disappointed , the below is my recv code , could you help to see it ? thanks in advance , BTW , I use SOCK_STREAM in the socket
C++
      void Communication::receive(char buffer[], int BUFFER_SIZE){
        static const int small_buf = 512;
        char buf[small_buf];
        bzero(buf,small_buf);
        int length = 0;
        char* pp = buffer;
        do{
            length = recv(socket_,buf,small_buf,0);
             if(length < 0)
                {
                connect_state_ = false;
                break;
                }else if(length == small_buf){
                connect_state_ = true;
                memcpy(pp, buf, small_buf);
                pp = pp+small_buf;  
            }else if(length < small_buf && length > 0)
            {
                connect_state_ = true;
                memcpy(pp, buf, length);
                pp = pp + length;
            }else if(length == 0)
            {
                break;
            }
        }while(length > 0);
//merge the small_buf into a big buffer which is big enough (50*1024), which is one of function's param 
}


What I have tried:

I changed the buf length , 512, 1024 ,2048 , even I change SOCK_DGRAW to send json and then recv , but the result is same , recv is very very slow , I use sync to communicate with a php website in apache server
Posted
Updated 24-Jun-16 1:01am
v2
Comments
Mohibur Rashid 24-Jun-16 6:15am    
Are you sure that your query is working fast?
Member 12601798 26-Jun-16 20:50pm    
yes , the server response is very short , and i write the server code

Your code looks straitforward, as in many other places I have seen. The influence of buffer size is smaller as you think. You should also use a 8k buffer, so you get all data at once.

My tip is that your server or network is slow. Take a look at it. You need to find the bottleneck. Try a local fetch on the server.

Tip 2: Use Wireshark for investigating the network traffic.
 
Share this answer
 
Comments
Member 12601798 26-Jun-16 5:49am    
thank your advance , but I I find the reason why the reponse is so slowly , in face , I use the below c++ code to send Post request,

string PostString::prepare_send(const string& host, const string& path , const string& content_type){
string stream;
int content_length = str_.length();
//cout << "content length is " << content_length << endl;
char buffer[20] = { 0 };
num_to_buffer(content_length, buffer, 10);
string str;
cp_buffer_string(buffer, 20, str);
stream += "POST ";
stream += path;
stream += " HTTP/1.1\r\n";
stream += "Host: ";
stream += host;
stream += "\r\n";
stream += "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3\r\n";
if("json" == content_type){

stream += "Content-Type: application/json\r\n";
}else{
stream += "Content-Type: application/x-www-form-urlencoded\r\n";
}
stream += "Content-Length: ";
stream += str;
stream += "\r\n";
//stream += "Connection: keep-alive\r\n";
stream += "Connection: close\r\n";
stream += "\r\n";
stream += str_;
return stream;

}
please note :Connection: keep-alive\r\n";
stream += "Connection: close\r\n";

I used the keep_alive mode , http will keep to open the connection , the server will suppose the client will continue to send post request, so the server will wait, in fact , I will not send any more in the session, so the server will close the connection when time is out , that is all :)
Is your socket blocking or non-blocking?

With blocking sockets, the recv call will only return when there are data available (return value > 0), a timeout occured (return value 0), or an error occured (return value -1).

Your code will wait for data, receives it, and waits again. This will be an endless loop if you have not set a timeout value. With a timeout value, the recv call will return after that time when no data has been received. According to your description this seems to be the case with a timeout value of 10 seconds.

With non-blocking sockets you should use some kind of signaling when data are available and call recv repeatedly while it returns -1 and errno is EAGAIN or EWOULDBLOCK.

I suggest to use a non-blocking socket. With blocking sockets you have to analyse the received data immediately to detect if all data has been received or there are more to come.
 
Share this answer
 
Comments
Member 12601798 26-Jun-16 5:52am    
thank your advance , sync and async has nothing to improve the situation, I find the reason why the reponse is so slowly , in fact , I use the below c++ code to send Post request,

string PostString::prepare_send(const string& host, const string& path , const string& content_type){
string stream;
int content_length = str_.length();
//cout << "content length is " << content_length << endl;
char buffer[20] = { 0 };
num_to_buffer(content_length, buffer, 10);
string str;
cp_buffer_string(buffer, 20, str);
stream += "POST ";
stream += path;
stream += " HTTP/1.1\r\n";
stream += "Host: ";
stream += host;
stream += "\r\n";
stream += "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3\r\n";
if("json" == content_type){

stream += "Content-Type: application/json\r\n";
}else{
stream += "Content-Type: application/x-www-form-urlencoded\r\n";
}
stream += "Content-Length: ";
stream += str;
stream += "\r\n";
//stream += "Connection: keep-alive\r\n";
stream += "Connection: close\r\n";
stream += "\r\n";
stream += str_;
return stream;

}
please note :Connection: keep-alive\r\n";
stream += "Connection: close\r\n";

I used the keep_alive mode , http will keep to open the connection , the server will suppose the client will continue to send post request, so the server will wait, in fact , I will not send any more in the session, so the server will close the connection when time is out , that is all :)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900