Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[ace-users] RE: How do I get hostname and port info for remote end of socket?

167 views
Skip to first unread message

Kelly F. Hickel

unread,
Nov 27, 2001, 9:38:27 AM11/27/01
to
Well, as far as the examples go, I'm already using that code, and it
doesn't seem to work. I've read chapter 4 of the book, and it doesn't
really talk about it, but does have a code snippet, which also looks
like the code that I have. As far as ACE:init(), the fragment below is
part of an ACE service, so yes, there's no doubt that ACE:init() has
been called. The socket is in a good state, as I go one to read data
from it with no problem.

Does anyone have any other ideas?

-Kelly

-----Original Message-----
From: Douglas C. Schmidt [mailto:sch...@cs.wustl.edu]
Sent: Monday, November 26, 2001 3:05 PM
To: Kelly F. Hickel; ace-...@cs.wustl.edu
Subject: Re: How do I get hostname and port info for remote end of
socket?

Hi Kelly,

>> I've been trying to steal code from the ACE test/samples to come up
>> with a way to print out the hostname and port of the the application
>> which is connecting to my service (the application is NOT ACE, the
>> service is). I've tried a couple of different things (PRF and sample
>> below) with no luck.

There are examples of how to do this in

$ACE_ROOT/examples/C++NPv1/Logging_Handler.cpp
$ACE_ROOT/examples/C++NPv1/Logging_Server.cpp

All of this is documented in Chapter 4 of C++NPv1
<www.cs.wustl.edu/~schmidt/ACE/> which is due out in about 2 weeks.

>> Even though the functions return 0 indicating
>> success, the hostname I get back is always the hostname of the local
>> machine, the ip address is always 0.0.0.0, and the port is always 0.
>>
>> I'm probably doing something stupid here, but I just can't see it.

Are you remembering to call ACE::init() before calling any of the ACE
socket calls?

Thanks,

Doug

>> ACE VERSION: 5.2
>>
>> HOST MACHINE and OPERATING SYSTEM: Windows 2000 Professional
>> TARGET MACHINE and OPERATING SYSTEM, if different from HOST:
>> COMPILER NAME AND VERSION (AND PATCHLEVEL): VisualStudio 6,
>> service pack 3
>>
>> AREA/CLASS/EXAMPLE AFFECTED:
>> [What example failed? What module failed to compile?]
>>
>> DOES THE PROBLEM AFFECT:
>> COMPILATION? NO
>> If so, what do your $ACE_ROOT/ace/config.h and
>> $ACE_ROOT/include/makeinclude/platform_macros.GNU
contain?
>> LINKING? NO
>> On Unix systems, did you run make realclean first?
>> EXECUTION? YES
>> OTHER (please specify)?
>> [Please indicate whether ACE, your application, or both are
affected.]
>> application
>>
>> SYNOPSIS:
>> Can't figure out how to get hostname and port of remote end of active
>> socket.
>>
>> DESCRIPTION:
>> Below is a cut down function that shows the code that I've tried
>> (taken from various ace tests/samples).
>>
>> REPEAT BY:
>> [What you did to get the error; include test program or session
>> transcript if at all possible. ]
>>
>> SAMPLE FIX/WORKAROUND:
>> [If available ]
>>
>>
>>
>>
>> ********* Sample Function *********
>> void myfunc(ACE_SOCK_Stream *sock) :
>> {
>>
>> // Determine hostname and ip address
>> char hostname[400] = "(unknown)";
>> struct sockaddr_in addr;
>> int addr_size = sizeof(addr);
>> if(!ACE_OS::getpeername(sock->get_handle(), ACE_reinterpret_cast
>> (sockaddr *,&addr), &addr_size)){
>> ACE_INET_Addr a((struct sockaddr_in*)&addr, addr_size);
>> char ipaddr[350]="(unknown)";
>> (void)a.get_host_name(hostname, sizeof(hostname));
>> hostname_ = hostname;
>> printf("QP_Agent hostname %s, created at 0x%x,
>> sock=0x%x.\n", hostname, this, sock);
>> if(a.addr_to_string(ipaddr, sizeof(ipaddr)))
>> strcpy(ipaddr, "(Unknown)");
>>
>> // try a different function
>> ACE_INET_Addr aa;
>> if(sock->get_remote_addr(aa) == 0) {
>> printf("got it, host = %s, port = %d\n",
>> aa.get_host_name (),
>> aa.get_port_number ());
>> }
>>
>>
>> // Program goes on to successfully read data from socket
>>
>> }
>>
>>
>>


--
Dr. Douglas C. Schmidt, Associate Professor TEL: (949) 824-1901
Dept of Electrical & Computer Engineering FAX: (949) 824-2321
616E Engineering Tower WEB:
www.ece.uci.edu/~schmidt/
University of California, Irvine, 92697-2625 NET: sch...@uci.edu

Douglas C. Schmidt

unread,
Nov 27, 2001, 9:45:00 AM11/27/01
to
Hi Kelly,

>> Well, as far as the examples go, I'm already using that code, and it
>> doesn't seem to work.

Have you tried running the example from the book *directly*, rather
than cutting+pasting the code that you posted earlier?

>> I've read chapter 4 of the book, and it doesn't really talk about
>> it, but does have a code snippet, which also looks like the code
>> that I have. As far as ACE:init(), the fragment below is part of
>> an ACE service, so yes, there's no doubt that ACE:init() has been
>> called. The socket is in a good state, as I go one to read data
>> from it with no problem.
>>
>> Does anyone have any other ideas?

Perhaps there's a problem with your DNS configuration?

Take care,

Doug

Kelly F. Hickel

unread,
Nov 27, 2001, 10:18:12 AM11/27/01
to
Doug,
I was never able to run the samples, I could build them after
fixing a problem with std::getline in Logging_Client.cpp, but whenever I
try to run any of the .exes, I get a message like:

server.run(): The requested name is valid and was found in the database,
but it does not have the correct associated data being resolved for.

I couldn't find any instructions on setting these up, and I was short on
time, so I didn't pursue that, I just copied the code. Maybe I need
some sort of setup file (didn't think I needed an svc.conf, but maybe I
do?)?

I don't believe it can be a DNS issue for two reasons:
1) I helped set up our DNS (and so it must be perfect!), and I've tested
forward and reverse lookups, etc.
2) Even if the DNS is broken, I should be getting valid IP addresses and
ports, not 0.0.0.0.

-Kelly
-----Original Message-----
From: Douglas C. Schmidt [mailto:sch...@cs.wustl.edu]
Sent: Tuesday, November 27, 2001 8:43 AM
To: ace-...@cs.wustl.edu; Kelly F. Hickel
Subject: Re: [ace-users] RE: How do I get hostname and port info for
remote end of socket?

Douglas C. Schmidt

unread,
Nov 27, 2001, 11:39:29 AM11/27/01
to
Hi Kelly,

>> I was never able to run the samples, I could build them after
>> fixing a problem with std::getline in Logging_Client.cpp, but whenever I
>> try to run any of the .exes, I get a message like:
>>
>> server.run(): The requested name is valid and was found in the database,
>> but it does not have the correct associated data being resolved for.

That smells like a DNS problem to me... Anytime you see the phrase
"requested name... database... data being resolved for" that sounds
like DNS.

>> I couldn't find any instructions on setting these up, and I was short on
>> time, so I didn't pursue that, I just copied the code. Maybe I need
>> some sort of setup file (didn't think I needed an svc.conf, but maybe I
>> do?)?

Nope, everything runs just fine "out-of-the-box" if you're OS and DNS
are configured properly.

>> I don't believe it can be a DNS issue for two reasons:
>> 1) I helped set up our DNS (and so it must be perfect!), and I've tested
>> forward and reverse lookups, etc.
>> 2) Even if the DNS is broken, I should be getting valid IP addresses and
>> ports, not 0.0.0.0.

As usual, when all the "possible" sources of errors don't solve the
problem, it's time to reconsider the "impossible" errors. I recommend
that you do so some additional debugging with the original C++NPv1
examples and see where that error message you reported is coming from.

As always, if you need additional help with ACE, I recommend the
services of Steve Huston <shu...@riverace.com>.

Kelly F. Hickel

unread,
Nov 27, 2001, 1:23:09 PM11/27/01
to
Doug,
Well, I found out why the examples don't work "OOB", it's
because you have to specify the port you want it to listen on, on the
command line, unless you have a "ace_logger" service port defined. So,
there is no DNS issue, there is a compiler problem with the
Logging_Client.cpp on windows visual studio 6 with service pack 3 (the
std::getline call).

The addr stuff does work, but it's getting the ACE_INET_addr value from
the acceptor (at least in the Iterative logging service). We're using
both the reactor and proactor (depending on whether we're on windows or
unix), and I don't know if those have that option, but in any case, I'm
way down in an ACE_Task thread, the "actor" has long since moved on to
other things, all I have is an ACE_SOCK_Stream and I want to get the
hostname, ip, and port of the other end.

I'll keep looking, but I wanted to clear up what problem I'm trying to
solve, and the problems I've run into with the examples.

-Kelly

-----Original Message-----
From: Douglas C. Schmidt [mailto:sch...@cs.wustl.edu]
Sent: Tuesday, November 27, 2001 10:34 AM
To: ace-...@cs.wustl.edu; Kelly F. Hickel
Subject: Re: [ace-users] RE: How do I get hostname and port info for
remote end of socket?

Kelly F. Hickel

unread,
Nov 27, 2001, 2:26:06 PM11/27/01
to

Rich,

            We don’t actually use ACE_Svc_Handler, but I looked at it, and if you instantiate it on ACE_SOCK_Stream, then you’re basically doing the same thing that I am.  I have an ACE_SOCK_Stream so that’s the equivalent of calling this->peer().  When I call get_remote_addr, it returns a success indicator, but the resulting ACE_INET_Addr structure contains all zeros for the address.

-Kelly

 

-----Original Message-----
From: Newman, Rich [mailto:RNe...@directv.com]
Sent: Tuesday, November 27, 2001 12:27 PM
To: Kelly F. Hickel; Douglas C. Schmidt; ace-...@cs.wustl.edu
Subject: RE: [ace-users] RE: How do I get hostname and port info for remote end of socket?

 

Hi Kelly,

If you have the Svc_Handler, then you have all you need.

The ACE_Svc_Handler<ACE_SOCK_STREAM, ...> template class includes all of the ACE_SOCK, ACE_INET_Addr, and ACE_SOCK_IO classes.  The accessor method is peer(), which returns a reference to the underlying ACE_SOCK_IO class.  Take a look in there, and in ACE_SOCK, and you'll see that you have methods such as:

get_remote_addr(), get_remote_host(), get_addr(), etc. 

So, inside your handler all you need is:

        ACE_INET_Addr   local_addy, remote_addy;
        this->peer().get_local_addr(local_addy);
        const char *local_host = local_addy.get_host_name();

        this->peer().get_remote_addr(remote_addy);
        const char *remote_host = remote_addy.get_host_name(); 

 

Naturally, you'll want to check for return codes in your own, code.  I've eliminated error checking for clarity.  These method invocations can happen anytime after a socket has connected, (in the case of the "remote_*" calls, or anytime the Svc_Handler has been constructed in the case of the "local_*" methods.  Usually, I do this sort of thing in my open(void *) method.

--Rich

Ossama Othman

unread,
Nov 27, 2001, 2:38:31 PM11/27/01
to
Hi,

On Tue, Nov 27, 2001 at 01:21:55PM -0600, Kelly F. Hickel wrote:
> We don't actually use ACE_Svc_Handler, but I looked at it,
> and if you instantiate it on ACE_SOCK_Stream, then you're basically
> doing the same thing that I am. I have an ACE_SOCK_Stream so that's the
> equivalent of calling this->peer(). When I call get_remote_addr, it
> returns a success indicator, but the resulting ACE_INET_Addr structure
> contains all zeros for the address.

I'm jumping in a bit late here so I may have missed something. Did
you actually initialize the ACE_SOCK_Stream (e.g. with an
ACE_SOCK_Acceptor or an ACE_SOCK_Connector)?

-Ossama
--
Ossama Othman <oss...@ece.uci.edu>
Distributed Object Computing Laboratory, Univ. of California at Irvine
1024D/F7A394A8 - 84ED AA0B 1203 99E4 1068 70E6 5EB7 5E71 F7A3 94A8

Kelly F. Hickel

unread,
Nov 27, 2001, 2:45:57 PM11/27/01
to
Ossama,
The ACE_SOCK_Stream was handed down, through either a Reactor or
Proactor (depending on the platform), and seems to be in a good state,
as the next thing the service does is read data from it, which succeeds
nicely. For some reason, I just can't get an ACE_INET_Addr that isn't
full of zeros. I've stepped down into ACE_OS::getpeername to see it
call the windows getpeername, and everything seems OK, getpeername
returns 0, but the address is all zeros.
-Kelly

-----Original Message-----
From: Ossama Othman [mailto:oss...@doc.ece.uci.edu]
Sent: Tuesday, November 27, 2001 1:37 PM
To: ace-...@cs.wustl.edu
Subject: Re: [ace-users] RE: How do I get hostname and port info for
remote end of socket?

Douglas C. Schmidt

unread,
Nov 27, 2001, 3:38:21 PM11/27/01
to
Hi Kelly,

>> The ACE_SOCK_Stream was handed down, through either a Reactor
>> or Proactor (depending on the platform), and seems to be in a good
>> state, as the next thing the service does is read data from it,
>> which succeeds nicely. For some reason, I just can't get an
>> ACE_INET_Addr that isn't full of zeros. I've stepped down into
>> ACE_OS::getpeername to see it call the windows getpeername, and
>> everything seems OK, getpeername returns 0, but the address is all
>> zeros.

You might drop down a level and try using the C-level APIs to see if
they work. Check out

$ACE_ROOT/examples/IPC_SAP/SOCK_SAP/C-inserver.cpp

for a good place to start. My guess is it's a configuration problem
on your machine or a bug with your program since this stuff seems to
work fine with ACE.

Kelly F. Hickel

unread,
Nov 27, 2001, 4:07:53 PM11/27/01
to
Well, I think I've (just) figured it out. We're using the Proactor on
windows, which uses asynchronous IO. We ran into this problem a couple
years ago in our windows servers, it's just taken me this long to figure
it out again. In Windows, when using IO completion ports, you can't use
getpeername(), you have to use GetAcceptExSockaddrs() (I don't suppose
ACE wraps that, does it?) to fetch the ip addrs from the Overlapped IO
memory buffer. So, I'm going to have to figure out if we're using
asynch or synch IO, and if async, use the ACE_SOCK::get_handle() and
then call GetAcceptExSockaddrs directly. Bummer.

Thanks,
Kelly

-----Original Message-----
From: Douglas C. Schmidt [mailto:sch...@cs.wustl.edu]

Sent: Tuesday, November 27, 2001 2:36 PM
To: ace-...@cs.wustl.edu
Subject: Re: [ace-users] RE: How do I get hostname and port info for
remote end of socket?

Douglas C. Schmidt

unread,
Nov 27, 2001, 4:13:09 PM11/27/01
to

Hi Kelly,

> In Windows, when using IO completion ports, you can't use
> getpeername(), you have to use GetAcceptExSockaddrs() (I don't
> suppose ACE wraps that, does it?)

No, I don't think so, but you could probably add it in such a way to
make it easier to write cross-platform code. Perhaps you could add a
new method called get_remote_addr_ex() that does an
ACE_OS::getpeername() on UNIX and a GetAcceptExSockaddrs() call on
Win32 and contribute this back to us.

Thanks,

Doug

Kelly F. Hickel

unread,
Nov 27, 2001, 4:19:44 PM11/27/01
to
Hmmmmm, I suppose on UNIX it would just call getpeername()? After all,
the point of wrapping it would be to have a single portable method that
can be called and give the correct results regardless.

An issue that has to be solved is that to know which to call (because
after all getpeername is valid on windows if not using overlapped IO)
for a given socket, you must know whether overlapped IO is in use for
that particular socket. At the moment, I'm not positive that can be
determined after the fact, but I'll take a look.

Maybe the right answer is (assuming you can determine on the fly if
overlapped IO was used) to make ACE_SOCK::get_remote_addr call
GetAcceptExSockaddrs() directly.......

-Kelly

-----Original Message-----
From: Douglas C. Schmidt [mailto:sch...@cs.wustl.edu]

Sent: Tuesday, November 27, 2001 3:12 PM
To: Kelly F. Hickel

Cc: ace-...@cs.wustl.edu
Subject: Re: [ace-users] RE: How do I get hostname and port info for
remote end of socket?

Douglas C. Schmidt

unread,
Nov 27, 2001, 4:25:48 PM11/27/01
to

Hi Kelly,

> Hmmmmm, I suppose on UNIX it would just call getpeername()?

I wouldn't do that since ACE_OS::getpeername() should already handle
all the portability issues on various versions of UNIX and other
operating systems.

> After all, the point of wrapping it would be to have a single
> portable method that can be called and give the correct results
> regardless.

Sure, if you can figure out how to make that work, that's obviously
the best bet.

> An issue that has to be solved is that to know which to call (because
> after all getpeername is valid on windows if not using overlapped IO)
> for a given socket, you must know whether overlapped IO is in use for
> that particular socket. At the moment, I'm not positive that can be
> determined after the fact, but I'll take a look.

I don't think you can know this.

> Maybe the right answer is (assuming you can determine on the fly if
> overlapped IO was used) to make ACE_SOCK::get_remote_addr call
> GetAcceptExSockaddrs() directly.......

Again, I don't think you can know this. Assume you *can't*, the next
best thing to do is to create a new method (e.g.,
get_remote_addr_ex()) that can work portably on both NT and non-NT
platforms when used in an asynchronous I/O context. At least that way
your application code should be relatively portable (assuming you're
using the ACE_Proactor on non-NT plaftorms).

Take care,

Doug

Douglas C. Schmidt

unread,
Nov 27, 2001, 4:26:41 PM11/27/01
to

Hi Kelly,

> In our case we actually use the Reactor on non-windows, that's
> why I was shooting for a single solution......

Right - and the solution I suggested will work just fine as a single
solution *as long as you call get_remote_addr_ex() in all cases*!

Take care,

Doug

Kelly F. Hickel

unread,
Nov 27, 2001, 4:27:52 PM11/27/01
to
Doug,

In our case we actually use the Reactor on non-windows, that's
why I was shooting for a single solution......

-Kelly

-----Original Message-----
From: Douglas C. Schmidt [mailto:sch...@cs.wustl.edu]
Sent: Tuesday, November 27, 2001 3:20 PM
To: Kelly F. Hickel
Cc: ace-...@cs.wustl.edu; Craig L. Ching
Subject: Re: [ace-users] RE: How do I get hostname and port info for
remote end of socket?

Kelly F. Hickel

unread,
Nov 28, 2001, 9:17:42 AM11/28/01
to
Doug,

The plot thickens (or twists)...

I've looked into this even more (learning more about the insides
of ACE than I ever wanted!), and it turns out that there is code in
ACE_Asynch_Acceptor to get it to pass local and remote addresses into
your ACE_Service_Handler, by setting pass_addresses to 1 on the open
call.

This is OK, and I could work a solution around this, but <pontificate>It
seems to me that a "righter" thing to do is:</pontificate> add a couple
of ACE_Addrs (one for local and one for remote) into ACE_SOCK, and add a
method ACE_SOCK::cacheAddrs(local, remote) which sets an internal flag
and caches the passed in values. This would be called from
ACE_Async_Acceptor::handle_accept(). This way, when a app later calls
ACE_SOCK::get_remote_addr() or ACE_SOCK::get_local_addr(), those
routines will check the internal flag, and if cached values exist, will
just return one of those. These routines could also cache the values
once they look them up, which would result in fewer system calls. That
might provide a performance boost on some platforms, I'm not sure.

What do you think?? Steve is this something Riverace might take on?
If so, can you provide me an estimate of cost? This doesn't *sound*
like too much work to me, but I've already spent too much time tracking
it down, and I'm behind schedule, so we might be able to pay Riverace to
do it.

-Kelly


-----Original Message-----
From: Kelly F. Hickel

Jonathan Biggar

unread,
Nov 28, 2001, 10:36:26 AM11/28/01
to
"Kelly F. Hickel" wrote:
> I've looked into this even more (learning more about the insides
> of ACE than I ever wanted!), and it turns out that there is code in
> ACE_Asynch_Acceptor to get it to pass local and remote addresses into
> your ACE_Service_Handler, by setting pass_addresses to 1 on the open
> call.
>
> This is OK, and I could work a solution around this, but <pontificate>It
> seems to me that a "righter" thing to do is:</pontificate> add a couple
> of ACE_Addrs (one for local and one for remote) into ACE_SOCK, and add a
> method ACE_SOCK::cacheAddrs(local, remote) which sets an internal flag
> and caches the passed in values. This would be called from
> ACE_Async_Acceptor::handle_accept(). This way, when a app later calls
> ACE_SOCK::get_remote_addr() or ACE_SOCK::get_local_addr(), those
> routines will check the internal flag, and if cached values exist, will
> just return one of those. These routines could also cache the values
> once they look them up, which would result in fewer system calls. That
> might provide a performance boost on some platforms, I'm not sure.
>
> What do you think?? Steve is this something Riverace might take on?
> If so, can you provide me an estimate of cost? This doesn't *sound*
> like too much work to me, but I've already spent too much time tracking
> it down, and I'm behind schedule, so we might be able to pay Riverace to
> do it.

Hmmm, except this doesn't work for datagram sockets where the addresses
can change with every incoming packet...

--
Jon Biggar
Floorboard Software
j...@floorboard.com
j...@biggar.org

Steve Huston

unread,
Nov 28, 2001, 10:39:53 AM11/28/01
to
Hi Kelly,

> I've looked into this even more (learning more about the insides
> of ACE than I ever wanted!), and it turns out that there is code in
> ACE_Asynch_Acceptor to get it to pass local and remote addresses into
> your ACE_Service_Handler, by setting pass_addresses to 1 on the open
> call.

Ok, good.

> This is OK, and I could work a solution around this, but <pontificate>It
> seems to me that a "righter" thing to do is:</pontificate> add a couple
> of ACE_Addrs (one for local and one for remote) into ACE_SOCK, and add a
> method ACE_SOCK::cacheAddrs(local, remote) which sets an internal flag
> and caches the passed in values.

You may have an idea here, but ACE_SOCK is the base class for more than
ACE_SOCK_Stream (ACE_MEM_Stream is also there, as well as ACE_SOCK_Dgram
which may not make sense to have a peer address). Further, the sizes of the
derived classes's addresses are different than an ACE_Addr.

> This would be called from
> ACE_Async_Acceptor::handle_accept(). This way, when a app later calls
> ACE_SOCK::get_remote_addr() or ACE_SOCK::get_local_addr(), those
> routines will check the internal flag, and if cached values exist, will
> just return one of those. These routines could also cache the values
> once they look them up, which would result in fewer system calls. That
> might provide a performance boost on some platforms, I'm not sure.

It would probably involve extra function calls, and maybe virtual functions,
which are really frowned upon at that layer of ACE.

> What do you think??

I think Microsoft should fix their socket implementation. It should not
matter at all that the socket was established asynchronously - the peer
address is available - if you send data, it gets to the right place, yes?

> Steve is this something Riverace might take on?

What, lobbying Microsoft? ;-)

> If so, can you provide me an estimate of cost? This doesn't *sound*
> like too much work to me, but I've already spent too much time tracking
> it down, and I'm behind schedule, so we might be able to pay Riverace to
> do it.

Riverace can look at this as part of a development contract, certainly. I'll
send you more information privately.

-Steve

--
Steve Huston Riverace Corporation
Email: shu...@riverace.com http://www.riverace.com
ACE Kits, Support, Consulting (508) 541-9180, FAX 541-9185
Installable Kits at http://www.riverace.com/ACE_Kits/kit-store.html


Kelly F. Hickel

unread,
Nov 28, 2001, 10:52:28 AM11/28/01
to
I wonder how/if datagram sockets work with async IO? Maybe the routines
I mentioned should be added as no ops to ACE_SOCK, and implemented in
ACE_SOCK_IO, which ACE_SOCK_Stream derives from but the datagram sockets
don't?

-Kelly

-----Original Message-----
From: Jonathan Biggar [mailto:j...@floorboard.com]
Sent: Wednesday, November 28, 2001 9:29 AM
To: Kelly F. Hickel
Cc: Douglas C. Schmidt; ace-...@cs.wustl.edu; Craig L. Ching; Steve
Huston
Subject: Re: [ace-users] RE: How do I get hostname and port info for
remote end of socket?

<snip>

Kelly F. Hickel

unread,
Nov 28, 2001, 10:59:54 AM11/28/01
to
Steve,
While I can't help but agree with you about the evil empire,
I've pretty much given up hope of having them do things the way I want
them to. On the other hand, if all OS vendors did things the "right"
way, then much of ACE wouldn't be needed!

Part of my problem is that I've approached ACE from the "start using it
and figure things out when you run into problems" approach (which I hope
to correct somewhat once the new book is available), so when I encounter
a problem I don't always have the right "view of the world according to
ACE" to figure out the best way to solve it. My suggestion of caching
the addrs was an attempt to help ACE hide the underlying complexity of
dealing with Microsoft's asynchronous IO system. As I said, I can work
around it with what ACE already gives me, but it involves having the
lower level of our code figure out if we're using sync or async io and
do the right thing, in addition to having our ACE_Serivce_Handler cache
the addresses until they're needed and somehow knowing when it's OK to
remove them from the cache. I can do all that, but it would be nice
just to be able to call getpeername() and not have to worry about it.
That would be the reason that my company might be willing to spend $$ to
have Riverace design and implement such a change, so that I can get on
with developing our service code instead of trying to resolve issues
with how ACE interacts with Microsoft.......

I'd REALLY like to make getpeername() just do the right thing (have I
mentioned that?), so any suggestions as to the "ACE way" to make this
happen are hereby solicited!

-Kelly

-----Original Message-----
From: Steve Huston [mailto:shu...@riverace.com]
Sent: Wednesday, November 28, 2001 9:38 AM
To: Kelly F. Hickel; Douglas C. Schmidt
Cc: ace-...@cs.wustl.edu; Craig L. Ching

Subject: Re: [ace-users] RE: How do I get hostname and port info for
remote end of socket?

Steve Huston

unread,
Nov 28, 2001, 11:34:45 AM11/28/01
to
Hi Kelly,

> While I can't help but agree with you about the evil empire,
> I've pretty much given up hope of having them do things the way I want
> them to.

I can certainly sympathize with this sentiment, but if their sockets are
broken, they should be pushed to fix it.

> On the other hand, if all OS vendors did things the "right"
> way, then much of ACE wouldn't be needed!

But they _all_ think they're doing it the right way ;-)

As Doug and I quote in C++ Network Programming, Vol 1: "The nice thing about
standards is that there are so many to pick from." Even if Microsoft's
getpeername worked like it should, getting sockets to work across Microsoft,
UNIX, et al; then throwing in threads would make life miserable for any
cross-platform effort if ACE hadn't already provided all the wrapper
facades. Adding on frameworks (which we discuss in C++ Network Programming,
Vol 2) makes ACE a killer toolkit.

> Part of my problem is that I've approached ACE from the "start using it
> and figure things out when you run into problems" approach

Worked for me :-)

> (which I hope to correct somewhat once the new book is available),

Right - we're writing as fast as possible!

> so when I encounter
> a problem I don't always have the right "view of the world according to
> ACE" to figure out the best way to solve it.

Right - I didn't mean to come across harshly on this - just trying to
prevent working down a path that's not likely to produce fruit.

> My suggestion of caching
> the addrs was an attempt to help ACE hide the underlying complexity of
> dealing with Microsoft's asynchronous IO system. As I said, I can work
> around it with what ACE already gives me, but it involves having the
> lower level of our code figure out if we're using sync or async io and
> do the right thing, in addition to having our ACE_Serivce_Handler cache

I have not seen your design, so I could be missing something, but if your
connections are set up by ACE_Asynch_Acceptor, your handler is derived from
ACE_Handler, and if you're using ACE_Acceptor, your handler would be derived
from ACE_Svc_Handler. The difference is known at compile time.

> I'd REALLY like to make getpeername() just do the right thing (have I
> mentioned that?), so any suggestions as to the "ACE way" to make this
> happen are hereby solicited!

First order of business is getting a definitive ruling on the Microsoft
behavior. Is it broken or not? If it is, pursue getting them to fix it, and
see about a workaround while they do.

Kelly F. Hickel

unread,
Nov 28, 2001, 11:41:08 AM11/28/01
to

-----Original Message-----
From: Steve Huston [mailto:shu...@riverace.com]
Sent: Wednesday, November 28, 2001 10:28 AM
To: Kelly F. Hickel
Cc: ace-...@cs.wustl.edu
Subject: Re: [ace-users] RE: How do I get hostname and port info for
remote end of socket?

<snip>


> so when I encounter
> a problem I don't always have the right "view of the world according
to
> ACE" to figure out the best way to solve it.

Right - I didn't mean to come across harshly on this - just trying to
prevent working down a path that's not likely to produce fruit.

[Kelly F. Hickel] I didn't think you were, I was just pointing out that
I might be trying to drive a screw with a hammer because it's all I've
got...

> My suggestion of caching
> the addrs was an attempt to help ACE hide the underlying complexity of
> dealing with Microsoft's asynchronous IO system. As I said, I can
work
> around it with what ACE already gives me, but it involves having the
> lower level of our code figure out if we're using sync or async io and
> do the right thing, in addition to having our ACE_Serivce_Handler
cache

I have not seen your design, so I could be missing something, but if
your
connections are set up by ACE_Asynch_Acceptor, your handler is derived
from
ACE_Handler, and if you're using ACE_Acceptor, your handler would be
derived
from ACE_Svc_Handler. The difference is known at compile time.

[Kelly F. Hickel] We can switch (via svc.conf) our IO method at runtime,
so it's not known at compile time. The code that is trying to get the
hostname/port is way down deep and does know ANYTHING about acceptors,
reactors, proactors etc, all it know is that it has a socket, some data,
and needs to send a message out.

> I'd REALLY like to make getpeername() just do the right thing (have I
> mentioned that?), so any suggestions as to the "ACE way" to make this
> happen are hereby solicited!

First order of business is getting a definitive ruling on the Microsoft
behavior. Is it broken or not? If it is, pursue getting them to fix it,
and
see about a workaround while they do.

[Kelly F. Hickel] They don't think it's broken.

Steve Huston

unread,
Nov 28, 2001, 12:03:39 PM11/28/01
to
Hi Kelly,

> > My suggestion of caching
> > the addrs was an attempt to help ACE hide the underlying complexity of
> > dealing with Microsoft's asynchronous IO system. As I said, I can
> work
> > around it with what ACE already gives me, but it involves having the
> > lower level of our code figure out if we're using sync or async io and
> > do the right thing, in addition to having our ACE_Serivce_Handler
> cache
>
> I have not seen your design, so I could be missing something, but if
> your
> connections are set up by ACE_Asynch_Acceptor, your handler is derived
> from
> ACE_Handler, and if you're using ACE_Acceptor, your handler would be
> derived
> from ACE_Svc_Handler. The difference is known at compile time.
> [Kelly F. Hickel] We can switch (via svc.conf) our IO method at runtime,
> so it's not known at compile time.

Ok... but if you're using asynch accept, do you have a class derived from
ACE_Service_Handler? If so, you can have it get the addresses when
established. Override addresses() in your class, and stash them. Similarly,
if using reactive accept, you probably have a class derived from
ACE_Svc_Handler - in open(), grab the peer address and stash it.

> The code that is trying to get the
> hostname/port is way down deep and does know ANYTHING about acceptors,
> reactors, proactors etc, all it know is that it has a socket, some data,
> and needs to send a message out.

Ok, I see, but ACE provides the tools you need to grab the address when the
socket is opened, in either scenario, without affecting this level of your
code.

Helping to design your code to handle the differences can be done under a
development contract, if you are interested in that.

Best regards,

Kelly F. Hickel

unread,
Nov 28, 2001, 12:59:31 PM11/28/01
to
Steve,

> -----Original Message-----
> From: Steve Huston [mailto:shu...@riverace.com]
> Sent: Wednesday, November 28, 2001 10:55 AM
> To: ACE-users
> Subject: Re: [ace-users] RE: How do I get hostname and port info for
> remote end of socket?
>

This is exactly what I was talking about when I said I can work around
it. I just didn't want to have to do it, as I'd rather fix getpeername
if I can.
I've looked for the doc that says getpeername doesn't work on AcceptEx
sockets, I can't find it, so I was probably wrong about it being the
documented behavior. I will be contacting Microsoft to see what they
have to say for themselves.

Steve Huston

unread,
Nov 28, 2001, 6:11:01 PM11/28/01
to
Hi Kelly,

> > Ok... but if you're using asynch accept, do you have a class derived
> from
> > ACE_Service_Handler? If so, you can have it get the addresses when
> > established. Override addresses() in your class, and stash them.
> This is exactly what I was talking about when I said I can work around
> it. I just didn't want to have to do it, as I'd rather fix getpeername
> if I can.

I see.

> I've looked for the doc that says getpeername doesn't work on AcceptEx
> sockets, I can't find it, so I was probably wrong about it being the
> documented behavior. I will be contacting Microsoft to see what they
> have to say for themselves.

Was this what you were thinking of:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/wsa
piref_17jm.asp where it says:

When this operation is successfully completed, sAcceptHandle can be passed,
but to the following functions only:

ReadFile
WriteFile
send
recv
TransmitFile
closesocket


That would be a major league guffaw, even for Microsoft...

Kelly F. Hickel

unread,
Nov 28, 2001, 7:11:46 PM11/28/01
to
Yep. That's the one. Maybe I won't bother calling them now, since it's
documented they aren't likely to change it (not that they were if it
wasn't documented!).
-Kelly

-----Original Message-----
From: Steve Huston [mailto:shu...@riverace.com]
Sent: Wednesday, November 28, 2001 5:02 PM
To: ACE-users
Subject: Re: [ace-users] RE: How do I get hostname and port info for
remote end of socket?

0 new messages