BorlandTalk.com Forum Index BorlandTalk.com
Borland discussion newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Problem with recv

 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> C++ Builder (Internet Socket)
View previous topic :: View next topic  
Author Message
Eduardo Jauch
Guest





PostPosted: Fri Feb 23, 2007 3:08 am    Post subject: Problem with recv Reply with quote



Hi, I write this code (most part based on unix exemples, so, forgive me
for anything...)

#include <stdio.h>
#include <conio.h>
#include <winsock2.h>

char buffer[4000];
char buf[4000];

#pragma argsused
int main(int argc, char* argv[])
{
SOCKET sockfd;
int portno, n;
struct sockaddr_in serv_addr;
struct hostent *server;

WORD wVersionRequested;
WSADATA wsaData;
int err;

wVersionRequested = MAKEWORD( 2, 0 );

err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
return -1;
}

if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) !=
0 ) {
WSACleanup( );
return -1;
}

sockfd = socket(AF_INET, SOCK_STREAM, 0);

if (sockfd == INVALID_SOCKET)
{
int erro = WSAGetLastError();
printf("%d", erro);
}
else
printf("Socket inicializado...\n");

sockaddr_in addr;
addr.sin_family = AF_INET;
portno = 80;
addr.sin_port = htons(portno);
addr.sin_addr.s_addr = inet_addr("200.214.74.5");

n = connect(sockfd, (struct sockaddr*)&addr, sizeof(addr));
printf("\nResposta de connect: %d", n);
if(n != 0) return 0;

strcpy(buffer,"GET /agendamento-web/login?redirect=/agenciadores.do
HTTP/1.1\r\nHost: www.visto-eua.com.br\r\n");

n = send(sockfd, buffer, sizeof(buffer) - 1, 0);
if (n < 0)
{
printf("\nERROR writing to socket");
return 0;
}
else
printf("\nSend...OK");

n = recv(sockfd, buf, sizeof(buf) - 1, 0);

printf("\n\nEncerrado o recebimento de dados do site");
buf[n] = '\0';

printf("\n\nConteúdo do buffer: %s", buf);
printf("\n\nPressione qualquer tecla");
getch();
closesocket(sockfd);
return 0;
}

The problem is that to recv return pass much time (much more than 2
minutes while I can access the site in seconds), and always return n = 0.

I'm trying to read the RFC documents related to this tupe of connection
(HTTP, TCP, etc...)

I found that Host: xxx is obrigatory for HTTP 1.1 requests...

Can someone tell me if I'm forgeting to pass something on the send or if
there some error on it?

Thanks in advance Smile
Back to top
Remy Lebeau (TeamB)
Guest





PostPosted: Fri Feb 23, 2007 4:09 am    Post subject: Re: Problem with recv Reply with quote



"Eduardo Jauch" <eduardo.jauch (AT) gmail (DOT) com> wrote in message
news:45de060c$1 (AT) newsgroups (DOT) borland.com...

Quote:
if (sockfd == INVALID_SOCKET)

You are not exiting if the socket was not created.

Quote:
n = connect(sockfd, (struct sockaddr*)&addr, sizeof(addr));
printf("\nResposta de connect: %d", n);
if(n != 0) return 0;

You are not calling closesocket() or WSACleanup() if connect() fails.

Quote:
strcpy(buffer,"GET
/agendamento-web/login?redirect=/agenciadores.do
HTTP/1.1\r\nHost: www.visto-eua.com.br\r\n");

I do not recommend implementing the HTTP protocol manually. It is a
very complex protocol. You really should stick with premade HTTP
libraries/components that do all of the work for you. For example,
you are missing a CRLF in the string above. In order for the server
to know when the headers have ended, you must send a blank line after
than, but you are not doing that.

Quote:
n = send(sockfd, buffer, sizeof(buffer) - 1, 0);

You are not taking into account that send() can return less than the
amount you asked it to send. You need to call send() in a loop until
all data has been accepted. Also, you are sending the entire buffer
(all 4000 bytes), not just the string data you copied into it. You
should be using strlen() instead of sizeof().

Quote:
n = recv(sockfd, buf, sizeof(buf) - 1, 0);
snip
buf[n] = '\0';

You are not taking into account that recv() can return < 0. When that
happen, you will be accessing memory outside of your buffer.

Quote:
The problem is that to recv return pass much time (much more than
2 minutes while I can access the site in seconds), and always return
n = 0.

That is because you are not terminating your HTTP request correctly,
so the server never sends a reply at all, and recv() ends up timing
out.

Quote:
I found that Host: xxx is obrigatory for HTTP 1.1 requests...

That has nothing to do with this issue.


Gambit
Back to top
Eduardo Jauch
Guest





PostPosted: Fri Feb 23, 2007 6:56 am    Post subject: Re: Problem with recv Reply with quote



Remy Lebeau (TeamB) escreveu:
Quote:
You are not exiting if the socket was not created.


That's because i'm only begining the code Smile
There lot's of things yet to implement.

Quote:
n = connect(sockfd, (struct sockaddr*)&addr, sizeof(addr));
printf("\nResposta de connect: %d", n);
if(n != 0) return 0;

You are not calling closesocket() or WSACleanup() if connect() fails.

Again, even this been an error, I'm only doing some fast tests, not
doing the code to work "really" :)

Quote:
I do not recommend implementing the HTTP protocol manually. It is a
very complex protocol. You really should stick with premade HTTP
libraries/components that do all of the work for you.

I admit that implementing the HTTP protocol is very complex Smile
But seens very funny no? ;)

I'm reading the documentation and this was the first thing I see.
But I'm not a "professional" C++ programmer. I really make some code and
some money with them, but is not my first activity.

So I really like to learning something knew Smile Even something of this
complexity ;)

This was only a first try. Smile I'm yet in the beginning of the lecture of
the documentation. Smile I need learn much more about C++ too :)

Quote:
For example,
you are missing a CRLF in the string above. In order for the server
to know when the headers have ended, you must send a blank line after
than, but you are not doing that.

Well... I really was thinking that the last '\r\n' was that... I don't
know that was necessary another... I'll try it :)

Quote:
You are not taking into account that send() can return less than the
amount you asked it to send. You need to call send() in a loop until
all data has been accepted.

You're right Smile I see this on other forum too, but I was only trying to
"receive" some data... Not the entire page. :)

Also, you are sending the entire buffer
Quote:
(all 4000 bytes), not just the string data you copied into it. You
should be using strlen() instead of sizeof().


I'm read on another forum exactly the oposite... Now I'm in doubt...

Sizeof will return 4000 to me...
If the buffer is empty (full of '\0'), strlen will return 4000 too? Not 0?

Quote:
You are not taking into account that recv() can return < 0. When that
happen, you will be accessing memory outside of your buffer.


I forget this... :$ hehe

Quote:
That is because you are not terminating your HTTP request correctly,
so the server never sends a reply at all, and recv() ends up timing
out.

So, it's explained :)

I'll take all the tips and information seriously Smile
This will help me much, I'm certain :)


Thank's Gambit Smile
Back to top
Eduardo Jauch
Guest





PostPosted: Fri Feb 23, 2007 7:02 am    Post subject: Re: Problem with recv Reply with quote

Add one more "\r\n" to the final worked perfectly!!! :)

thanks!!! Smile
Back to top
Remy Lebeau (TeamB)
Guest





PostPosted: Fri Feb 23, 2007 9:10 am    Post subject: Re: Problem with recv Reply with quote

"Eduardo Jauch" <eduardo.jauch (AT) gmail (DOT) com> wrote in message
news:45de3b88 (AT) newsgroups (DOT) borland.com...

Quote:
I'm read on another forum exactly the oposite... Now I'm in doubt...

Your code wants to transmit 59 bytes (61 after you add the necessary
CRLF) to the server, but you are telling send() to transmit 5999 bytes
instead. That is completely wrong, and whoever told you otherwise is
lying.

Quote:
Sizeof will return 4000 to me...

As it should be. That is what it is supposed to do. But that is not
the correct size to use.

Quote:
If the buffer is empty (full of '\0'), strlen will return 4000 too?

No, it will not. It will return the actual length of the character
data, up to but not including the first '\0' byte. If the buffer is
completely empty, it will return 0. When you put your string data in
it, it will return 59/61 instead.


Gambit
Back to top
Eduardo Jauch
Guest





PostPosted: Fri Feb 23, 2007 8:59 pm    Post subject: Re: Problem with recv Reply with quote

Sorry. Smile
I was thinking of the buf (with recv, not send).

Thanks Smile
Back to top
Display posts from previous:   
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> C++ Builder (Internet Socket) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.