Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C++ (http://www.velocityreviews.com/forums/f39-c.html)
-   -   newbie: socket api (http://www.velocityreviews.com/forums/t955847-newbie-socket-api.html)

Thomas Kaufmann 12-26-2012 09:56 PM

newbie: socket api
 
Hi there,

I use the socket-API. My Problem is:

I have a function (yes, a function not a method). And I want return either the struct sockaddr_in or sockaddr_in6. How can do this? I tried a void-pointer but there is an error-message.

Best regards.

Thomas

Victor Bazarov 12-26-2012 10:01 PM

Re: newbie: socket api
 
On 12/26/2012 4:56 PM, Thomas Kaufmann wrote:
> I use the socket-API. My Problem is:
>
> I have a function (yes, a function not a method). And I want return either the struct sockaddr_in or sockaddr_in6. How can do this? I tried a void-pointer but there is an error-message.


This is covered in the FAQ 5.8. Please read the FAQ before posting.
You can find FAQ here: http://www.parashift.com/c++-faq/

V
--
I do not respond to top-posted replies, please don't ask

Ian Collins 12-26-2012 10:02 PM

Re: newbie: socket api
 
Thomas Kaufmann wrote:
> Hi there,


Please wrap your lines!

> I use the socket-API. My Problem is:
>
> I have a function (yes, a function not a method). And I want return
> either the struct sockaddr_in or sockaddr_in6. How can do this? I
> tried a void-pointer but there is an error-message.


What did you try? What error did you get?

--
Ian Collins

Thomas Kaufmann 12-26-2012 10:13 PM

Re: newbie: socket api
 
Am Mittwoch, 26. Dezember 2012 23:02:08 UTC+1 schrieb Ian Collins:
> Thomas Kaufmann wrote:
>
> > Hi there,

>
>
>
> Please wrap your lines!
>
>
>
> > I use the socket-API. My Problem is:

>
> >

>
> > I have a function (yes, a function not a method). And I want return

>
> > either the struct sockaddr_in or sockaddr_in6. How can do this? I

>
> > tried a void-pointer but there is an error-message.

>
>
>
> What did you try? What error did you get?
>
>
>
> --
>
> Ian Collins


Here is my code:

#include "unp.h"
#include "init.h"

#include <exception>

void* InitAndConnect(int sockfd, int family, char *ip) {

// I want return this struct
struct sockaddr sa;

if (family == AF_INET) {

try {

struct sockaddr_in servaddr;;

bzero(&servaddr, sizeof(servaddr) );
servaddr.sin_family = family;
servaddr.sin_port = htons(SERV_PORT);

if (inet_pton(family, ip, &servaddr.sin_addr) <= 0) {
perror("inet_pton-error: ");
}

connect(sockfd, (SA*) &servaddr, sizeof(servaddr) );

// critical line
sa = servaddr;

} catch(std::exception& e) {
cout << e.what() << endl;
}

} else if (family == AF_INET6) {

struct sockaddr_in6 servaddr;

bzero(&servaddr, sizeof(servaddr) );
servaddr.sin6_family = AF_INET;
servaddr.sin6_port = htons(SERV_PORT);
inet_pton(family, ip, &servaddr.sin6_addr);

connect(sockfd, (SA*) &servaddr, sizeof(servaddr) );

// critical line
sa = servaddr;
}

// does' work
return sa;
}

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

int sockfd = socket(AF_INET, SOCK_STREAM, 0);
void* ptr = InitAndConnect(int sockfd, AF_INET, argv[1]) {

return 0;
}

Here are the errors:

xxx54@richard:~/myC++/unp/derplan> g++ -o init -Wall -pedantic -O3 init_test.cpp
init_test.cpp: In function ‘void* InitAndConnect(int, int, char*)’:
init_test.cpp:28:12: error: no match for ‘operator=’ in ‘sa = servaddr’
/usr/include/bits/socket.h:179:3: note: candidate is: sockaddr& sockaddr::operator=(const sockaddr&)
init_test.cpp:46:12: error: no match for ‘operator=’ in ‘sa = servaddr’
/usr/include/bits/socket.h:179:3: note: candidate is: sockaddr& sockaddr::operator=(const sockaddr&)
init_test.cpp:50:10: error: cannot convert ‘sockaddr’ to ‘void*’ inreturn
init_test.cpp: In function ‘int main(int, char**)’:
init_test.cpp:56:31: error: expected primary-expression before ‘int’
init_test.cpp:56:61: error: expected ‘,’ or ‘;’ before ‘{’ token
init_test.cpp:55:7: warning: unused variable ‘sockfd’
init_test.cpp:56:9: warning: unused variable ‘ptr’
init_test.cpp:59:1: error: expected ‘}’ at end of input
init_test.cpp: In function ‘void* InitAndConnect(int, int, char*)’:
init_test.cpp:51:1: warning: control reaches end of non-void function
xxx54@richard:~/myC++/unp/derplan>

Ian Collins 12-26-2012 10:28 PM

Re: newbie: socket api
 
Thomas Kaufmann wrote:
>


** Please clean up the mess that dreadful google interface makes of your
quotes.

> Here is my code:
>
> #include "unp.h"
> #include "init.h"
>
> #include <exception>
>
> void* InitAndConnect(int sockfd, int family, char *ip) {
>
> // I want return this struct
> struct sockaddr sa;


Then why don't you?

> if (family == AF_INET) {
>
> try {


Why have a try block here?

> struct sockaddr_in servaddr;;
>
> bzero(&servaddr, sizeof(servaddr) );


Just use
sockaddr_in servaddr = {0};

rather than calling bzero.

> servaddr.sin_family = family;
> servaddr.sin_port = htons(SERV_PORT);
>
> if (inet_pton(family, ip, &servaddr.sin_addr) <= 0) {
> perror("inet_pton-error: ");


Should you carry on if this fails?

> }
>
> connect(sockfd, (SA*) &servaddr, sizeof(servaddr) );
>
> // critical line
> sa = servaddr;
>
> } catch(std::exception& e) {
> cout << e.what() << endl;
> }
>
> } else if (family == AF_INET6) {
>
> struct sockaddr_in6 servaddr;
>
> bzero(&servaddr, sizeof(servaddr) );
> servaddr.sin6_family = AF_INET;
> servaddr.sin6_port = htons(SERV_PORT);
> inet_pton(family, ip, &servaddr.sin6_addr);
>
> connect(sockfd, (SA*) &servaddr, sizeof(servaddr) );
>
> // critical line
> sa = servaddr;
> }
>
> // does' work
> return sa;


Are you surprised?

You could return something like

struct Address
{
int family;
union {
sockaddr_in v4;
sockaddr_in6 v6;
} servaddr;
};

--
Ian Collins

Miquel van Smoorenburg 12-26-2012 10:58 PM

Re: newbie: socket api
 
In article <f067934f-c936-48ea-854f-5220718c5d36@googlegroups.com>,
Thomas Kaufmann <tokauf@googlemail.com> wrote:
>Here is my code:
>
>void* InitAndConnect(int sockfd, int family, char *ip) {
>
> // I want return this struct
> struct sockaddr sa;


You should return a struct sockaddr_storage, since a plain struct
sockaddr isn't big enough for a struct sockaddr_in6. That,
or a pointer of type struct sockaddr, that points to a
_in or _in6.

> if (family == AF_INET) {
>
> try {
>
> struct sockaddr_in servaddr;;
>
> bzero(&servaddr, sizeof(servaddr) );
> servaddr.sin_family = family;
> servaddr.sin_port = htons(SERV_PORT);


Should probably be something like

struct sockaddr_in *serveraddr = (struct sockaddr_in *)&sa;
servaddr->sin_family = family;
servaddr->sin_port = htons(SERV_PORT);
... etc

> // does' work
> return sa;


But why not use getaddrinfo() to do all the dirty work for you.
Note that you don't even have to pass in "family" since
getaddrinfo() figures that out for you.

int InitAndConnectchar *ip)
{
struct addrinfo hints = { 0 };
hints.ai_flags = AI_NUMERICHOST;
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;

struct addrinfo *res;
int r = getaddrinfo(ip, SERV_PORT, &hints, &res);
if (r != 0) {
fprintf(stderr, "%s/%s: %s\n", ip, SERV_PORT,
gai_strerror(r));
return NULL;
}

int sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (sock < 0)
return -1;
int ok = connect(sock, res->ai_addr, res->ai_addrlen);
if (ok != 0) {
close(sock);
sock = -1;
}
freeaddrinfo(res);

return sock;
}

Mike.

woodbrian77@gmail.com 12-27-2012 06:26 AM

Re: newbie: socket api
 
On Wednesday, December 26, 2012 3:56:26 PM UTC-6, Thomas Kaufmann wrote:
> Hi there,
>
>
>
> I use the socket-API. My Problem is:
>
>
>
> I have a function (yes, a function not a method). And I want return either the struct sockaddr_in or sockaddr_in6. How can do this? I tried a void-pointer but there is an error-message.
>
>


Here's some code similar to what Mike posted:
http://webEbenezer.net/misc/getaddrinfo_wrapper.cc
http://webEbenezer.net/misc/connect_wrapper.cc

Those files and others are part of the archive here --
http://webEbenezer.net/build_integration.html
..

Brian
Ebenezer Enterprises
http://webEbenezer.net

Thomas Kaufmann 12-27-2012 09:00 PM

Re: newbie: socket api
 
Am Mittwoch, 26. Dezember 2012 22:56:26 UTC+1 schrieb Thomas Kaufmann:
> Hi there,
>
>
>
> I use the socket-API. My Problem is:
>
>
>
> I have a function (yes, a function not a method). And I want return either the struct sockaddr_in or sockaddr_in6. How can do this? I tried a void-pointer but there is an error-message.



Thanks folks for your help!

Best regards

Thomas

Jorgen Grahn 12-29-2012 05:07 PM

Re: newbie: socket api
 
On Wed, 2012-12-26, Miquel van Smoorenburg wrote:
> In article <f067934f-c936-48ea-854f-5220718c5d36@googlegroups.com>,
> Thomas Kaufmann <tokauf@googlemail.com> wrote:
>>Here is my code:
>>
>>void* InitAndConnect(int sockfd, int family, char *ip) {

....

> But why not use getaddrinfo() to do all the dirty work for you.
> Note that you don't even have to pass in "family" since
> getaddrinfo() figures that out for you.


+1. For some bizarre reason, people seem to be unaware of
getaddrinfo(), even though it has existed for 10+ years and is
documented in the classic works on socket programmming.

Use it. It saves work, avoids bugs and provides features you'll
probably neglect to provide if you do it manually.

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .

Bill Cunningham 12-31-2012 04:10 AM

Re: newbie: socket api
 
Ian Collins wrote:
> Thomas Kaufmann wrote:


I would just like to say this one thing about this code. I've worked with
the same functions in C with the unix socket api. I *think* bzero is
depricated for memset now.

>> bzero(&servaddr, sizeof(servaddr) );
>> servaddr.sin6_family = AF_INET;
>> servaddr.sin6_port = htons(SERV_PORT);
>> inet_pton(family, ip, &servaddr.sin6_addr);
>>
>> connect(sockfd, (SA*) &servaddr, sizeof(servaddr) );
>>
>> // critical line
>> sa = servaddr;
>> }
>>
>> // does' work
>> return sa;

>
> Are you surprised?
>
> You could return something like
>
> struct Address
> {
> int family;
> union {
> sockaddr_in v4;
> sockaddr_in6 v6;
> } servaddr;
> };





All times are GMT. The time now is 06:14 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.