We help IT Professionals succeed at work.

We've partnered with Certified Experts, Carl Webster and Richard Faulkner, to bring you a podcast all about Citrix Workspace, moving to the cloud, and analytics & intelligence. Episode 2 coming soon!Listen Now

x

simple socket program

btocakci
btocakci asked
on
Medium Priority
1,206 Views
Last Modified: 2012-05-06
Hi! I am tryin' to write a simple socket program to retrieve an internet page. But i get a segmentation fault. I am confused. This is the first problem. The second one is the piece where i put a comment. How to configure the connection there?

Thanks for your help.
#include<stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include<stdlib.h>
 
int main()
{
 
struct addrinfo info;
struct addrinfo *servinfo;  // will point to the results
 struct hostent *he;
struct sockaddr_in *sa;
 
int socket_define,n;
char message[10000];
char* ip;
 
memset(&info, 0, sizeof info); // make sure the struct is empty
 
info.ai_family = AF_UNSPEC;     // don't care IPv4 or IPv6
info.ai_socktype = SOCK_STREAM; // TCP stream sockets
info.ai_flags = AI_PASSIVE;     // fill in my IP for me
 
ip = (char*)malloc(sizeof(char)*15);
he = (struct hostent*) malloc(sizeof(struct hostent));
sa = (struct sockaddr_in*) malloc(sizeof(struct sockaddr_in));
 
  if ((he = gethostbyname("www.google.com")) == NULL) {  // get the host info
        printf("An error occurred while resolving the domain name");
        return -1;
    }
    else
    {
      printf("The IP of the domain name is resolved succesfully:\n");
      ip = (char*)inet_ntoa(he->h_addr_list[0]);
      printf("%s\n", ip);
 
    }
 
 
socket_define = socket(AF_INET, SOCK_STREAM, 0);
if(socket_define<0) {error("An error occurred while creating the socket\n");return -1;}
else printf("Socket is created succesfully\n");	
 
 
/*
 
 
Here, should i set something else? I donot have enough knowledge to configure the sa variable
 
*/
 
 
if(connect(socket_define, (struct sockaddr*)&sa,sizeof(sa)) <0) error("Error connecting to socket\n");
else printf("Connection is OK..\n"); 
 
  sprintf(message, "Get /%s HTTP/1.1\r\nHost: %s\r\n\r\n", "", ip);
 
printf("%s",message);
 
      n = recv(socket_define, message, sizeof(message), 0);
	if(n==-1) error("Socket read error. ");
 
 
 
return 0;
}

Open in new window

Comment
Watch Question

masheikSoftware Engineer
CERTIFIED EXPERT
Commented:

Not the solution you were looking for? Getting a personalized solution is easy.

Ask the Experts

Author

Commented:
thanks for your reply. i change my code according to the information in this page.
now i get an couldnot connect: connection refused error. What may be the problem.

#include<stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include<stdlib.h>
 
 
char *build_get_query(char *host, char *page);
 
int main()
{
 
struct addrinfo info;
struct addrinfo *servinfo;  // will point to the results
 struct hostent *he;
struct sockaddr_in *sa;
char *get;
int socket_define,n,tmpres;
char message[10000];
char* ip;
 
 
ip = (char*)malloc(sizeof(char)*16);
he = (struct hostent*) malloc(sizeof(struct hostent));
sa = (struct sockaddr_in*) malloc(sizeof(struct sockaddr_in));
 
  if ((he = gethostbyname("www.yeditepe.edu.tr")) == NULL) {  // get the host info
        printf("An error occurred while resolving the domain name");
        return -1;
    }
    else
    {
      printf("The IP of the domain name is resolved succesfully:\n");
      ip = (char*)inet_ntoa(he->h_addr_list[0]);
      printf("%s\n", ip);
 
    }
 
 
socket_define = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(socket_define<0) {error("An error occurred while creating the socket\n");return -1;}
else printf("Socket is created succesfully\n");	
 
 
 
sa->sin_family = AF_INET;
tmpres = inet_pton(AF_INET, ip, (void *)(&(sa->sin_addr.s_addr)));
 
if( tmpres < 0){perror("Can't set remote->sin_addr.s_addr"); exit(1); }else if(tmpres == 0)
  {fprintf(stderr, "%s is not a valid IP address\n", ip); exit(1); }
 
 
  sa->sin_port = htons(80);
 
 
if(connect(socket_define, (struct sockaddr *)sa, sizeof(struct sockaddr)) < 0){
 
    perror("Could not connect");
 
    exit(1);
 
  }
 
 
  get = build_get_query(ip, "");
 
  fprintf(stderr, "Query is:\n<<START>>\n%s<<END>>\n", get);
 /*
   //   n = recv(socket_define, message, sizeof(message), 0);
	//if(n==-1) error("Socket read error. ");
 
*/
 
return 0;
}
 
 
 
char *build_get_query(char *host, char *page)
 
{
 
  char *query;
 
  char *getpage = page;
 
  char *tpl = "GET /%s HTTP/1.0\r\nHost: %s\r\nUser-Agent: %s\r\n\r\n";
 
  if(getpage[0] == '/'){
 
    getpage = getpage + 1;
 
    fprintf(stderr,"Removing leading \"/\", converting %s to %s\n", page, getpage);
 
  }
 
  // -5 is to consider the %s %s %s in tpl and the ending \0
 
  query = (char *)malloc(strlen(host)+strlen(getpage)+strlen("HTMLGET 1.0")+strlen(tpl)-5);
 
  sprintf(query, tpl, getpage, host, "HTMLGET 1.0");
 
  return query;
 
}

Open in new window

masheikSoftware Engineer
CERTIFIED EXPERT

Commented:
can you post the error message?
masheikSoftware Engineer
CERTIFIED EXPERT

Commented:
or try for other urls
masheikSoftware Engineer
CERTIFIED EXPERT

Commented:
is it working?

Author

Commented:
i tried with lots of domain names, but same error: connection refused.
masheikSoftware Engineer
CERTIFIED EXPERT

Commented:
ok,sorry, i can't support you further, because, i am not familiar with Linux,

I, Hope my answers helpful
CERTIFIED EXPERT
Top Expert 2009
Commented:
There are several problems with your code.

Below is a clean version that simply connects to a server, and then disconnects again. Use this code without modification, and if it doesn't work, please post the output you get here.

Once it works, you can start modifying the code to send and receive whatever you need.

I also recommend the excellent tutorial "Beej's Guide to Network Programming" :

        http://beej.us/guide/bgnet/
#include <stdio.h>
#include <stdlib.h>
 
#include <sys/types.h>
#include <sys/socket.h>
 
const char *host = "www.google.com";
const char *port = "80";
 
int main(void) {
  struct addrinfo hints;
  memset(&hints, 0, sizeof(hints));
  hints.ai_family = AF_UNSPEC;
  hints.ai_socktype = SOCK_STREAM;
 
  int ret = 0;
  struct addrinfo *servinfo = 0;
  if ((ret = getaddrinfo(host, port, &hints, &servinfo)) != 0) {
    perror("getaddrinfo");
    return 1;
  }
  fprintf(stdout, "Got address info for %s:%s\n", host, port);
 
  int sock = 0;
  char ip[INET6_ADDRSTRLEN] = "";
  struct addrinfo *ai = 0;
  for (ai = servinfo; ai != 0; ai = ai->ai_next) {
    if ((sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol)) == -1) {
      perror("socket");
      continue;
    }
 
    if (ai->ai_addr->sa_family == AF_INET) {
      inet_ntop(ai->ai_family, &(((struct sockaddr_in*) ai->ai_addr)->sin_addr), ip, sizeof(ip));
    }
    else {
      inet_ntop(ai->ai_family, &(((struct sockaddr_in6*) ai->ai_addr)->sin6_addr), ip, sizeof(ip));
    }
 
    fprintf(stdout, "Trying to connect to %s\n", ip);
 
    if (connect(sock, ai->ai_addr, ai->ai_addrlen) == -1) {
      perror("connect");
      close(sock);
      continue;
    }
    break;
  }
 
  if (!ai) {
    fprintf(stderr, "ERROR : Failed to connect !\n");
    return 1;
  }
 
  freeaddrinfo(servinfo);
 
  fprintf(stdout, "Connected to %s\n", ip);
 
  /* now you can send and receive data ... */
 
  close(sock);
  fprintf(stdout, "Connection closed\n");
 
  return 0;
}

Open in new window

Access more of Experts Exchange with a free account
Thanks for using Experts Exchange.

Create a free account to continue.

Limited access with a free account allows you to:

  • View three pieces of content (articles, solutions, posts, and videos)
  • Ask the experts questions (counted toward content limit)
  • Customize your dashboard and profile

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.