0

I'm writing a client program that establishes a socket, connects to a remote server, and issues an HTTP request. However, I can't seem to connect to the remote server.

I believe I've done everything right, and even set up the correct port # for the sockaddr_in, but still I can't connect.

What am I missing?

#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

int main(int argc, char *argv[])
{
    FILE *fout;

    int i, c, sk;
    char *tk, host[64], path[64], fname[64], http_msg[256], buf[1024];

    struct sockaddr_in remote;
    struct hostent *hp;
    struct servent *se;

    if(argc != 2)
    {
        printf("Invalid number of arguments. Program terminating...\n");
        exit(1);
    }

    sk = socket(AF_INET, SOCK_STREAM, 0);
    remote.sin_family = AF_INET;

    c = 0;
    tk = strtok(argv[1], "/");
    while(tk != NULL)
    {
        if(c == 0)
            strcpy(host, tk);
        else if(c == 1)
            strcpy(path, tk);
        else
            strcpy(fname, tk);
        ++c;
        tk = strtok(NULL, "/");
    }

    snprintf(http_msg, 256, "GET /%s/%s HTTP/1.1\r\nHost: %s\r\nConnection: close\r\n\n", path, fname, host);

    hp = gethostbyname(host);
    if(hp == NULL)
    {
        printf("Can't find host %s. Program terminating...\n", host);
        exit(1);
    }

    se = getservbyname("http", "tcp");
    remote.sin_port = ntohs(se->s_port);

    if(connect(sk, (struct sockaddr*)&remote, sizeof(remote)) < 0)
    {
        printf("Connection attempt failed. Program terminating...\n");
        exit(1);
    }

    send(sk, http_msg, sizeof(http_msg) + 1, 0);
    recv(sk, buf, sizeof(buf), 0);
    printf("%s\n", buf);

    return 0;
}
4
  • You missed to inject hp into remote: bcopy((char *)hp->h_addr, (char *)&remote.sin_addr.s_addr, hp->h_length); Commented Apr 7, 2015 at 4:20
  • I just tried that and am still not able to connect. Does it matter if I use memcpy instead? Commented Apr 7, 2015 at 4:22
  • with this line just before the connect, the connection is done. How do you check if you are connected ? Commented Apr 7, 2015 at 4:36
  • Which line? I test the connection with if(connect(sk, (struct sockaddr *)&remote, sizeof(remote)) < 0) Commented Apr 7, 2015 at 4:40

2 Answers 2

1

I got it

the problem is with the line

remote.sin_port = ntohs(se->s_port);

You don't need to convert it. This code works for me:

if(argc != 2)                                                              
{                                                                          
    printf("Invalid number of arguments. Program terminating...\n");       
    exit(1);                                                               
}                                                                          

bzero(&remote, sizeof(remote));                                            
sk = socket(AF_INET, SOCK_STREAM, 0);                                      
remote.sin_family = AF_INET;                                               

c = 0;                                                                     
tk = strtok(argv[1], "/");                                                 
while(tk != NULL)                                                          
{                                                                          
    if(c == 0)                                                             
        strcpy(host, tk);                                                  
    else if(c == 1)                                                        
        strcpy(path, tk);                                                  
    else                                                                   
        strcpy(fname, tk);                                                 
    ++c;                                                                   
    tk = strtok(NULL, "/");                                                
}                                                                          

snprintf(http_msg, 256, "GET /%s/%s HTTP/1.1\r\nHost: %s\r\nConnection: close\r\n\r\n", path, fname, host); 

hp = gethostbyname(host);                                                  
if(hp == NULL)                                                             
{                                                                          
    printf("Can't find host %s. Program terminating...\n", host);          
    exit(1);                                                               
}                                                                          

se = getservbyname("http", "tcp");                                         
printf("%d port\n", ntohs(se->s_port));                                    
remote.sin_port = se->s_port;                                              
bcopy((char *)hp->h_addr, (char *)&remote.sin_addr.s_addr, hp->h_length);  

if(connect(sk, (struct sockaddr*)&remote, sizeof(remote)) < 0)             
{                                                                          
    printf("Connection attempt failed. Program terminating...\n");         
    exit(1);                                                               
}                                                                          

send(sk, http_msg, sizeof(http_msg) + 1, 0);                               
recv(sk, buf, sizeof(buf), 0);                                             
printf("%s\n", buf);                                                       

return 0;                                                                  

}

Sign up to request clarification or add additional context in comments.

2 Comments

Why use bzero for remote? And I will try that. Unfortunately I'm not at my computer right now.
Stack value are not initialized, so you have to init it. By default I prefer to reset to 0, to be sure
0

Do this:

remote.sin_port = ntohs(se->s_port);
remote.sin_family = AF_INET;
remote.sin_addr = *((struct in_addr *) hp->h_addr);

That shoul'd do it. See the \r\n\r\n after Connection: close.

snprintf(http_msg, 256, "GET /%s/%s HTTP/1.1\r\nHost: %s\r\nConnection: close\r\n\r\n", path, fname, host);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.