Problems with for loop and strings

Hi everybody. I am testing HTTP Headers and I have an strange problem. When I get the response of the server, it is the correct one the first time. If I use a for loop to send more than one request and get more than one response, this response seems to be overlapped with the previous ones.

To a better explanation of the problem I attach the code I am using and the output generated:

TCPSocket.h
-----------
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#ifndef _TCPSOCKET_H_
#define _TCPSOCKET_H_

class TCPSocket
{
	private:
		int localSocket;

	public:
		TCPSocket();
		~TCPSocket();
		void Connect(const char *host, int port);
		void Write(const char *data);
		char *Read();
};

#endif 


TCPSocket.cpp
-------------
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <iostream>
#include <string.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include "TCPSocket.h"

using namespace std;

TCPSocket::TCPSocket()
{
	localSocket = socket(AF_INET, SOCK_STREAM, 0);
	if (localSocket == -1) throw "No se puede crear el socket";
}

TCPSocket::~TCPSocket()
{
	int result = close(localSocket);
	if (result == -1) throw "No se puede cerrar el socket";
}

void TCPSocket::Connect(const char *host, int port)
{
	struct hostent *server = gethostbyname(host);
	if (server == NULL) throw "No se encuentra el host";

	struct sockaddr_in serverAddress;
	serverAddress.sin_family = AF_INET;
	serverAddress.sin_port = htons(port);
	serverAddress.sin_addr = *(struct in_addr *)(server->h_addr_list[0]);
	bzero(&(serverAddress.sin_zero), 8);

	cout << "Conectando con " << host << endl;
	cout << "Conectando con " << inet_ntoa(serverAddress.sin_addr) << endl;

	int result = connect(localSocket, (struct sockaddr *) &serverAddress, sizeof(serverAddress));
	if (result == -1) throw "No se puede conectar con el host";
}

void TCPSocket::Write(const char *data)
{
	int dataLength = strlen(data);
	int sent = send(localSocket, data, dataLength, 0);

	if (sent == -1) throw "No se pueden enviar los datos al host";
	if (sent != dataLength) throw "No se han podido enviar todos los datos al host";
}

char *TCPSocket::Read()
{
	const int MAX_DATA_LENGHT = 16384;
	char *data = new char[MAX_DATA_LENGHT];
	
	int received = recv(localSocket, data, MAX_DATA_LENGHT, 0);	
	if (received == -1) throw "No se pueden recibir los datos del host";

	return (data);
}


Main.cpp
--------
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <iostream>
#include "TCPSocket.h"

using namespace std;

int main()
{
	try
	{
		cout << "HTTP REQUEST" << endl;
		cout << "------------" << endl;
	
		// Establecemos la conexion con el servidor
		TCPSocket *tcpSocket = new TCPSocket();	
		tcpSocket->Connect("www.ubuntu.com", 80);

		// Generamos la peticion HTTP
		string request = "";
		request.append("HEAD / HTTP/1.1\r\n");
		request.append("Host: www.ubuntu.com\r\n");
		request.append("User-agent: My User Agent\r\n");
		request.append("\r\n");
	
		for(int i = 0; i < 5; i++)
		{
			// Realizamos la peticion HTTP
			tcpSocket->Write(request.c_str());

			// Obtenemos la respuesta del servidor
			char *data = tcpSocket->Read();
			string response = string(data);
		
			cout << endl << response << endl;
		}
		
		delete tcpSocket;
	
		return (0);
	}
		
	catch (const char *e)
	{
		cout << "Excepcion: " << e << endl;
		return (-1);
	}
}


The output generated is the following:


HTTP REQUEST
------------
Conectando con www.ubuntu.com
Conectando con 91.189.90.58

HTTP/1.1 200 OK
Date: Mon, 23 Jun 2014 10:26:31 GMT
Server: Apache/2.2.22 (Ubuntu)
Cache-Control: public, max-age=300
Vary: Accept-Encoding
Content-Type: text/html; charset=utf-8
Age: 26
Content-Length: 17555
X-Cache: HIT from avocado.canonical.com
X-Cache-Lookup: HIT from avocado.canonical.com:80
Via: 1.1 avocado.canonical.com:80 (squid/2.7.STABLE7)
Via: 1.1 www.ubuntu.com



HTTP/1.1 200 OK
Date: Mon, 23 Jun 2014 10:26:31 GMT
Server: Apache/2.2.22 (Ubuntu)
Cache-Control: public, max-age=300
Vary: Accept-Encoding
Content-Type: text/html; charset=utf-8
Age: 26
Content-Length: 17555
X-Cache: HIT from avocado.canonical.com
X-Cache-Lookup: HIT from avocado.canonical.com:80
Via: 1.1 avocado.canonical.com:80 (squid/2.7.STABLE7)
Via: 1.1 www.ubuntu.com

: 1.1 www.ubuntu.com



HTTP/1.1 200 OK
Date: Mon, 23 Jun 2014 10:26:31 GMT
Server: Apache/2.2.22 (Ubuntu)
Cache-Control: public, max-age=300
Vary: Accept-Encoding
Content-Type: text/html; charset=utf-8
Age: 26
Content-Length: 17555
X-Cache: HIT from avocado.canonical.com
X-Cache-Lookup: HIT from avocado.canonical.com:80
Via: 1.1 avocado.canonical.com:80 (squid/2.7.STABLE7)
Via: 1.1 www.ubuntu.com

: 1.1 www.ubuntu.com

: 1.1 www.ubuntu.com



HTTP/1.1 200 OK
Date: Mon, 23 Jun 2014 10:26:31 GMT
Server: Apache/2.2.22 (Ubuntu)
Cache-Control: public, max-age=300
Vary: Accept-Encoding
Content-Type: text/html; charset=utf-8
Age: 26
Content-Length: 17555
X-Cache: HIT from avocado.canonical.com
X-Cache-Lookup: HIT from avocado.canonical.com:80
Via: 1.1 avocado.canonical.com:80 (squid/2.7.STABLE7)
Via: 1.1 www.ubuntu.com

: 1.1 www.ubuntu.com

: 1.1 www.ubuntu.com

: 1.1 www.ubuntu.com



HTTP/1.1 200 OK
Date: Mon, 23 Jun 2014 10:26:31 GMT
Server: Apache/2.2.22 (Ubuntu)
Cache-Control: public, max-age=300
Vary: Accept-Encoding
Content-Type: text/html; charset=utf-8
Age: 26
Content-Length: 17555
X-Cache: HIT from avocado.canonical.com
X-Cache-Lookup: HIT from avocado.canonical.com:80
Via: 1.1 avocado.canonical.com:80 (squid/2.7.STABLE7)
Via: 1.1 www.ubuntu.com

: 1.1 www.ubuntu.com

: 1.1 www.ubuntu.com

: 1.1 www.ubuntu.com

: 1.1 www.ubuntu.com






So, a bigger loop, a bigger the response of the server. However, I know the response of the server is always the same.

I don't understand what it is happening and I am very worried about it.
I hope someone have the answer.

Thanks in advance.
You're not telling the server that you intend to reuse the connection. You need to set the relevant header.
Hi, but this not solve the problem. If I close de connection inside de for loop I obtain a similar result.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <iostream>
#include "TCPSocket.h"

using namespace std;

int main()
{
	try
	{
		for(int i = 0; i < 5; i++)
		{
			cout << "HTTP REQUEST" << endl;
			cout << "------------" << endl;
	
			// Establecemos la conexion con el servidor
			TCPSocket *tcpSocket = new TCPSocket();	
			tcpSocket->Connect("www.ubuntu.com", 80);

			// Generamos la peticion HTTP
			string request = "";
			request.append("HEAD / HTTP/1.1\r\n");
			request.append("Host: www.ubuntu.com\r\n");
			request.append("User-agent: My User Agent\r\n");
			request.append("\r\n");
	
			// Realizamos la peticion HTTP
			tcpSocket->Write(request.c_str());

			// Obtenemos la respuesta del servidor
			char *data = tcpSocket->Read();
			string response = string(data);
		
			cout << endl << response << endl;
			delete tcpSocket;
		}
	
		return (0);
	}
		
	catch (const char *e)
	{
		cout << "Excepcion: " << e << endl;
		return (-1);
	}
}


The output in this case is the following:


HTTP REQUEST
------------
Conectando con www.ubuntu.com
Conectando con 91.189.90.59

HTTP/1.1 200 OK
Date: Mon, 23 Jun 2014 12:19:21 GMT
Server: Apache/2.2.22 (Ubuntu)
Cache-Control: public, max-age=300
Vary: Accept-Encoding
Content-Type: text/html; charset=utf-8
Age: 167
Content-Length: 17555
X-Cache: HIT from jujube.canonical.com
X-Cache-Lookup: HIT from jujube.canonical.com:80
Via: 1.1 jujube.canonical.com:80 (squid/2.7.STABLE7)
Via: 1.1 www.ubuntu.com


HTTP REQUEST
------------
Conectando con www.ubuntu.com
Conectando con 91.189.90.58

HTTP/1.1 200 OK
Date: Mon, 23 Jun 2014 12:21:31 GMT
Server: Apache/2.2.22 (Ubuntu)
Cache-Control: public, max-age=300
Vary: Accept-Encoding
Content-Type: text/html; charset=utf-8
Age: 37
Content-Length: 17555
X-Cache: HIT from avocado.canonical.com
X-Cache-Lookup: HIT from avocado.canonical.com:80
Via: 1.1 avocado.canonical.com:80 (squid/2.7.STABLE7)
Via: 1.1 www.ubuntu.com

1.1 www.ubuntu.com


HTTP REQUEST
------------
Conectando con www.ubuntu.com
Conectando con 91.189.89.118

HTTP/1.1 200 OK
Date: Mon, 23 Jun 2014 12:21:50 GMT
Server: Apache/2.2.22 (Ubuntu)
Cache-Control: public, max-age=300
Vary: Accept-Encoding
Content-Type: text/html; charset=utf-8
Age: 18
Content-Length: 17555
X-Cache: HIT from nuno.canonical.com
X-Cache-Lookup: HIT from nuno.canonical.com:80
Via: 1.1 nuno.canonical.com:80 (squid/2.7.STABLE7)

al.com:80 (squid/2.7.STABLE7)
Via: 1.1 www.ubuntu.com

1.1 www.ubuntu.com


HTTP REQUEST
------------
Conectando con www.ubuntu.com
Conectando con 91.189.89.118

HTTP/1.1 200 OK
Date: Mon, 23 Jun 2014 12:21:50 GMT
Server: Apache/2.2.22 (Ubuntu)
Cache-Control: public, max-age=300
Vary: Accept-Encoding
Content-Type: text/html; charset=utf-8
Age: 18
Content-Length: 17555
X-Cache: HIT from nuno.canonical.com
X-Cache-Lookup: HIT from nuno.canonical.com:80
Via: 1.1 nuno.canonical.com:80 (squid/2.7.STABLE7)

(squid/2.7.STABLE7)

al.com:80 (squid/2.7.STABLE7)
Via: 1.1 www.ubuntu.com

1.1 www.ubuntu.com


HTTP REQUEST
------------
Conectando con www.ubuntu.com
Conectando con 91.189.90.59

HTTP/1.1 200 OK
Date: Mon, 23 Jun 2014 12:19:21 GMT
Server: Apache/2.2.22 (Ubuntu)
Cache-Control: public, max-age=300
Vary: Accept-Encoding
Content-Type: text/html; charset=utf-8
Age: 167
Content-Length: 17555
X-Cache: HIT from jujube.canonical.com
X-Cache-Lookup: HIT from jujube.canonical.com:80
Via: 1.1 jujube.canonical.com:80 (squid/2.7.STABLE7)
Via: 1.1 www.ubuntu.com

2.7.STABLE7)

al.com:80 (squid/2.7.STABLE7)
Via: 1.1 www.ubuntu.com

1.1 www.ubuntu.com





So the problem remain and I don't understand where is the error.
Thanks.
You have a problem with your code.
1
2
3
4
5
6
7
8
9
10
11
char *TCPSocket::Read()
{
        const int MAX_DATA_LENGHT = 16384;
        char *data = new char[MAX_DATA_LENGHT];

        int received = recv(localSocket, data, MAX_DATA_LENGHT, 0);
        if (received == -1) throw "No se pueden recibir los datos del host";

//      data[received] = 0;  // you forgot this line
        return (data);
}

Then later on:
1
2
                        char *data = tcpSocket->Read();
                        string response = string(data);


The buffer isn't null terminated, so the final string will have uninitialsed data.

Also, you don't free the buffer.
Last edited on
Topic archived. No new replies allowed.