Opened 8 years ago

Closed 8 years ago

#11030 closed defect (fixed)

Socket sample does not connect on Mac 2.9.0 RC4-6

Reported by: craigstark Owned by: vadz
Priority: high Milestone: 2.9.0
Component: old wxOSX/Carbon port Version: 2.9.0
Keywords: socket Cc: csomor
Blocked By: Blocking:
Patch: no

Description

First noticed in a project of mine and replicated in the socket sample. All works fine in Windows, but on a Mac compile of wxWidgets 2.9.0RC4 and RC6, attempt to open connection to an existing server on localhost fails with wxSOCKET_INVPORT:

Welcome to wxSocket demo: Client
Client ready

Trying to connect (timeout = 10 sec) ...
Failed ! Unable to connect 7

(note, error code added here)

My code (and sample) works on 2.8.10 here (just checked) on the Mac (OS X 10.5.7)

Craig

Change History (20)

comment:1 Changed 8 years ago by vadz

  • Cc csomor added
  • Keywords socket added
  • Priority changed from normal to high

I half hoped this was an isolated problem but there was just another report for it on the mailing list. So it looks like wxSocket is really broken under Mac (by my changes, I imagine) and this seems like critical enough to delay 2.9.0 again.

I'll try to look at this a.s.a.p. but, of course, if anybody else can debug this it would be great.

comment:2 Changed 8 years ago by vadz

I just realized that I was missing crucial information about this bug: do you use OS X Carbon or Cocoa version?

comment:3 Changed 8 years ago by craigstark

It's the Carbon version. I've not tried the Cocoa.

Craig

comment:4 Changed 8 years ago by joseph.wang

I've been working on socket related problem on MAC.

And it feels like the root cause is quit the same with this ticket.

I code a program to receive some specific packets on MAC with wxWidgets-2.9.0.

The code of receiving packets is at the function which has been registered to handle the socket event. And the socket is notified with the flag wxSOCKET_INPUT_FLAG.

But the socket event is not triggered on MAC.

As I traced through the code, I found that the implementation used to construct wxSocketBase is wxSocketImplUnix instead of wxSocketImplMac. So the socket event might not be registered to the system by the Core Foundation API of MAC.

To make it more clear, I attach the execution sequence step by step.

m_Socket = new wxDatagramSocket(localaddr, wxSOCKET_NONE | wxSOCKET_BROADCAST); //This line is in my own program.

//Then I step into the constructor of wxDatagramSocket
m_impl = wxSocketImpl::Create(*this)//Line 1973 of src/common/socket.cpp

//When I step into the Create() method, the next code to execute is line 72 of src/unix/sockunix.cpp
return new wxSocketImplUnix(wxsocket);

But according to my platform, I thought it would be more reasonable to execute wxSocketImplMac.
Please forgive me if I take it in the wrong way.

I configured with the following options

--prefix=/usr --enable-debug --disable-shared --with-mac --enable-std_iostreams

My system version is Mac OS X 10.4.10
Kernel version is Darwin 8.10.2

comment:5 Changed 8 years ago by vadz

  • Owner set to vadz
  • Status changed from new to accepted

Yes, this is definitely wrong, this code got completely broken by the latest round of refactoring and somehow I didn't notice it (well, actually I know how: because the unit tests only use console mode sockets which do work under Mac still probably).

I'll need to introduce another level of indirection into socket creation probably as under Mac we need to create different socket classes depending on whether we're in a console or GUI application...

comment:6 Changed 8 years ago by VZ

(In [61676]) Use CF socket manager in GUI OS X applications.

wxSocketManagerMac was never created under OS X since wxSocket code
refactoring as wxGUIAppTraits::GetSocketManager() wasn't overridden.

Doing this required an extra nasty hack with a global variable in the base
library which is used just to pass the socket manager pointer from the net
library to the core one without creating a dependency between them but this
seems unfortunately unavoidable.

See #11030.

comment:7 Changed 8 years ago by vadz

  • Resolution set to port to release branch
  • Status changed from accepted to portneeded

The socket sample now works for me, please let me know if you see any problems in your application with the latest svn trunk. If you can confirm that the latest code works for you, I'd backport it to 2.9.0 branch as it would be nice to fix this bug in 2.9.0 release.

Thanks in advance for your testing!

comment:8 Changed 8 years ago by craigstark

Thanks. I'm grabbing the trunk from the SVN now and will give it a go. FWIW, I'd also noticed the problem in code like:

wxFileSystem::AddHandler(new wxInternetFSHandler);
wxFileSystem fs;
wxFSFile *file= fs.OpenFile(wxT("http://www.yadda.com"));
...

I'll give that a check too.

Craig

comment:9 follow-up: Changed 8 years ago by craigstark

Sorry, but I can't seem to get the sample to even work. I must be doing something wrong:

svn checkout http://svn.wxwidgets.org/svn/wx/wxWidgets/trunk wxWidgets
...
mkdir universal; cd universal
../configure --enable-universal_binary --disable-shared --with-opengl
make
...
cd samples/sockets
make

Running the server and client, the client doesn't find the server. The server is, by default, listening on a bogus IP:

Welcome to wxSocket demo: Server
18:00:16: Creating server at 0.0.0.0:3000
18:00:16: Server listening at 0.0.0.0:3000

...
I added a addr.Hostname call to server.cpp so that it listens on a real IP address and it fires up with it:
Welcome to wxSocket demo: Server
18:08:23: Creating server at 127.0.0.1:3000
18:08:23: Server listening at 127.0.0.1:3000

Still no connect.
Welcome to wxSocket demo: Client
Client ready
18:08:34: Trying to connect to localhost:3000

...
Trying it on the actual localhost IP instead of the text doesn't help. Further, I cannot connect to anything in the "Test URL"
18:12:48: === URL test begins ===
18:12:48: Establishing connection to "http://www.google.com/"...
18:12:58: Error: Failed to retrieve URL "http://www.google.com/"
18:12:58: === URL test ends ===

18:13:28: === URL test begins ===
18:13:28: Establishing connection to "http://www.wxwidgets.org"...
18:13:38: Error: Failed to retrieve URL "http://www.wxwidgets.org"
18:13:38: === URL test ends ===

Craig

comment:10 follow-up: Changed 8 years ago by joseph.wang

It also happens in my environment.

It seems that socket event is still not triggered.

Here is the execution sequence by tracing with gdb.

//Line 1991 in the constructor of wxDatagramSocket in src/common/socket.cpp
m_impl = manager ? manager->CreateSocket(*this) : NULL;

//Line 122 in function wxSocketFDBaseManager::CreateSocket in include /wx/unix/private/sockunix.h
return new wxSocketImplUnix(wxsocket);

Does wxSocketImplMac still not participate on MAC?

comment:11 in reply to: ↑ 9 Changed 8 years ago by vadz

  • Status changed from portneeded to accepted

Replying to craigstark:

Sorry, but I can't seem to get the sample to even work. I must be doing something wrong:

svn checkout http://svn.wxwidgets.org/svn/wx/wxWidgets/trunk wxWidgets
...
mkdir universal; cd universal
../configure --enable-universal_binary --disable-shared --with-opengl

I didn't enable universal binaries for my build but I really don't see how could this matter... I also use (default) shared libraries, I'll need to rebuild with static ones to see if maybe something doesn't get linked in.

BTW, --with-opengl is unnecessary now, it's on by default.

The server is, by default, listening on a bogus IP:

Welcome to wxSocket demo: Server
18:00:16: Creating server at 0.0.0.0:3000
18:00:16: Server listening at 0.0.0.0:3000

It's not bogus, it just listens on all local interfaces, there is absolutely nothing wrong with it. The problem is surely elsewhere...

comment:12 in reply to: ↑ 10 Changed 8 years ago by vadz

Replying to joseph.wang:

Does wxSocketImplMac still not participate on MAC?

It does, OSXManagerSetter from src/osx/core/sockosx.cpp is supposed to set wxOSXSocketManagerCF to point to a Mac-specific class which then should be returned from wxAppTraitsBase::GetSocketManager() in src/osx/core/utilsexc_base.cpp.

Do you use static linking too? If so, I'm almost sure the problem is indeed just that src/osx/core/sockosx.cpp is being optimized away by the linker, I'll test and fix this soon if it's the case but in the meanwhile could you please try rebuild using shared libraries?

comment:13 Changed 8 years ago by craigstark

OK, so a Universal Binary with shared libraries has the sockets demo work here for me. So far, so good.

Craig

comment:14 Changed 8 years ago by VZ

(In [61689]) Force linking of src/osx/core/sockosx.cpp.

Without this the file was omitted by linker entirely in the static build and
the correct socket manager wasn't used for the GUI applications (see #11030).

comment:15 Changed 8 years ago by vadz

  • Resolution changed from port to release branch to port to stable
  • Status changed from accepted to portneeded

I could reproduce the bug in the static builds and I've fixed it there in the above-mentioned revision, please reopen if the problem still persists.

comment:16 Changed 8 years ago by joseph.wang

The socket on MAC now works perfectly with both sample and my own program.
Thank you for your hard working.

comment:17 Changed 8 years ago by joseph.wang

I find that if I bind the UDP socket to the IP of my MAC (ex: 192.168.1.2) instead of 0.0.0.0,
the Socket Event is not triggered to receive the packet. Somehow it succeeded to send out packets.

If I create the socket in this way:

wxIPV4address localaddr;
localaddr.Hostname("192.168.1.195");
localaddr.Service("9527");
m_Socket = new wxDatagramSocket(localaddr, wxSOCKET_NONE | WXSOCKET_BROADCAST);

then I can only send out packets but fail to receive packets for the socket event is not triggered.

However, if I create the socket in this way:

wxIPV4address localaddr;
localaddr.Hostname("0.0.0.0"); 
localaddr.Service("9527");
m_Socket = new wxDatagramSocket(localaddr, wxSOCKET_NONE | WXSOCKET_BROADCAST);

I can send out packets and receive packets for the socket event works well.

Is this another issue or related to this ticket?

comment:18 Changed 8 years ago by vadz

I don't see how could it be related so it's probably better to open a new bug report for it. Could you please do it and also let me know if:

  1. This bug is Mac-only too or if it also happens under e.g. Linux?
  2. I understand correctly that it fails like this with UDP only, not with TCP sockets?

TIA!

comment:19 Changed 8 years ago by VZ

(In [61734]) Back port of wxSocket-related fixes from trunk.

This patch combines the changes from the following trunk revisions:

It refactors wxSocketImpl creation to use a Mac-specific version of it in GUI
Mac applications which fixes generation of socket events under Mac (see #11030)
and also fixes bug in wxSocketServer::WaitForAccept() (see #11107).

comment:20 Changed 8 years ago by vadz

  • Resolution changed from port to stable to fixed
  • Status changed from portneeded to closed
Note: See TracTickets for help on using tickets.