9
struct hostent *lh               = gethostbyname(hostname);

int socketDescriptor             = socket(AF_INET,SOCK_STREAM, 0);

sockaddr_in socketInfo;

memset(&socketInfo, 0, sizeof(socketInfo));
socketInfo.sin_family            = AF_INET;
socketInfo.sin_addr.s_addr       = ((in_addr *)(lh->h_addr))->s_addr;
socketInfo.sin_port              = htons(portNumber);

connect(socketDescriptor,&socketInfo,sizeof(socketInfo));

When trying to compile, I get the following error:

error: cannot convert ‘sockaddr_in*’ to ‘const sockaddr*’ for argument ‘2’ to ‘int connect(int, const sockaddr*, socklen_t)’

Things look "by the book", but I am missing something (obviously). What is it?

1
  • 12
    Your lining-up-the-assignments makes my eyes hurt. Commented May 29, 2011 at 20:29

4 Answers 4

14

I think you are missing struct on sockaddr_in socketInfo. So it should be struct sockaddr_in socketInfo.

Also casting socketInfo to struct sockaddr * would be nice.

connect(socketDescriptor,&socketInfo,sizeof(socketInfo));

Should be

connect(socketDescriptor,(struct sockaddr *) &socketInfo,sizeof(socketInfo));
Sign up to request clarification or add additional context in comments.

Comments

3
  struct addrinfo *server;
  struct addrinfo hints; 

    memset(&hints, 0, sizeof(struct addrinfo));/*set hints*/
    hints.ai_family = AF_UNSPEC;    /* Allow IPv4 or IPv6 */
    hints.ai_socktype = SOCK_STREAM; 
    hints.ai_flags = 0;
    hints.ai_protocol = 0;          /* Any protocol */

 getaddrinfo(srvname,port,&hints,&server); /*get server ip fit args*/

 sid = socket(server->ai_family, server->ai_socktype,server->ai_protocol)
 connect(sid,server->ai_addr, server->ai_addrlen)

Those are some codesnipets that will work and that you can start from.

What happens here is that I set up one struct with all the intel and than combine it with some more info to get one nice all pointers fit structure too pass to connect. hope that helps

4 Comments

+1 for getaddrinfo. Note that the memset is not really needed. You could just initialize struct sockaddr hints = { 0 };
@R: +1 to both of you. Although I think you mean struct addrinfo hints = { 0 };
Also, if you call getaddrinfo(), you better call freeaddrinfo()
@Nemo @R Thanks for those infos, fyi freeaddrinfo was called but I did not list it here.
2

The socket interfaces, in addition to being very old, are deliberately broken in this way. The sockaddr_* structs implicitly start with the same members of sockaddr so it's safe to cast them to the "base" type. struct sockaddr also has an sa_family member so you can also decide at runtime given a struct sockaddr* which "derived" (though not really) type to cast it to.

So, the smallest thing you can do to change this is cast the struct sockaddr_in* to struct sockaddr*. Normally this would be very offensive. But don't worry; in this instance everyone is doing it. I might even prefer to cast to void* because it's fewer characters and you'll get the implict conversion to struct sockaddr*.

However... A few other unrelated points:

  1. gethostbyname can fail. In fact it happens pretty often, say when the user types in a bogus address. Your program will crash when that happens. Check to see if it returned NULL to avoid this.

  2. Actually, gethostbyname has been superseded by getaddrinfo. Use that. It will get you protocol-independence so that you're not tied to IPv4. It also returns you a struct sockaddr* so you don't have to do the ugly cast.

1 Comment

+1 all of OP's difficulties would go away just by dropping these deprecated interfaces.
1

If it was just the const it would work, but obviously sockaddr and sockaddr_in are different types.

1 Comment

Yes, but forgetting the cast should only elicit a warning, not an error.

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.