This issue tracker has been migrated to GitHub ,
and is currently read-only.
For more information,
see the GitHub FAQs in the Python's Developer Guide.
Created on 2003年07月25日 14:43 by garth42, last changed 2022年04月10日 16:10 by admin. This issue is now closed.
| Messages (11) | |||
|---|---|---|---|
| msg17326 - (view) | Author: Garth Bushell (garth42) | Date: 2003年07月25日 14:43 | |
asyncore.poll is broken on windows. If a connection is refused happens it will hang for ever and never raise an exception. The Select statment never checks the exfds. This is needed as this is where windows reports failed connections. The documentation in the microsoft platform SDK mentions this. http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/select_2.asp The suggested fix is shown below althought this is untested. The correct error number is recived from getsockopt(SOL_SOCKET,SO_ERROR) def poll(timeout=0.0, map=None): if map is None: map = socket_map if map: r = []; w = []; e = [] for fd, obj in map.items(): if obj.readable(): r.append(fd) if obj.writable(): w.append(fd) if sys.platform == 'win32': if not obj.connected: e.append(fd) if [] == r == w == e: time.sleep(timeout) else: try: r, w, e = select.select(r, w, e, timeout) except select.error, err: if err[0] != EINTR: raise else: return if sys.platform == 'win32': for fd in e: obj = map.get(fd) if obj is None: continue errno = fs.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR) raise socket.error,(errno,socketerrorTab[error]) for fd in r: obj = map.get(fd) if obj is None: continue read(obj) for fd in w: obj = map.get(fd) if obj is None: continue write(obj) |
|||
| msg17327 - (view) | Author: John J Smith (johnjsmith) | Date: 2003年07月29日 12:49 | |
Logged In: YES user_id=830565 I was bitten by the same problem. My workaround (in a Tkinter application) is given below. Would it make sense to modify poll() to simply add the union of r and w to e, and call handle_error() for any fd in e? Workaround: try: self.connect(send_addr) except socket.error: self.handle_error() if sys.platform == 'win32': # Win98 select() doesn't seem to report errors for a # non-blocking connect(). self.__connected = 0 self.__frame.after(2000, self.__win_connect_poll) ... if sys.platform == 'win32': def __win_connect_poll (self): if self.__connected: return e = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR) if e in (0, errno.EINPROGRESS, errno.WSAEINPROGRESS): self.__frame.after(2000, self.__win_connect_poll) else: try: str = socket.errorTab[e] except KeyError: str = os.strerror(e) try: raise socket.error(e, str) except socket.error: self.handle_error() |
|||
| msg17328 - (view) | Author: Alexey Klimkin (klimkin) | Date: 2004年03月04日 08:23 | |
Logged In: YES user_id=410460 Patch #909005 fixes the problem. |
|||
| msg17329 - (view) | Author: Josiah Carlson (josiahcarlson) * (Python triager) | Date: 2007年01月07日 06:19 | |
I am looking into applying a variant of portions of #909005 to fix this bug. |
|||
| msg81863 - (view) | Author: Daniel Diniz (ajaksu2) * (Python triager) | Date: 2009年02月13日 03:27 | |
Looks like this one was solved in issue 909005, does anyone disagree? |
|||
| msg81978 - (view) | Author: Josiah Carlson (josiahcarlson) * (Python triager) | Date: 2009年02月13日 23:46 | |
According to Garth, sockets that don't connect on Windows get put into the error sockets list. According to John, you need to poll sockets to determine whether or not the attempted connection was refused. If Garth is right, the problem is fixed, though we aren't quite retrieving the correct error code on win32. If John is right, we need to repeatedly check for error conditions on sockets that are trying to connect to a remote host, and the problem is not fixed. |
|||
| msg176687 - (view) | Author: Marc Schlaich (schlamar) * | Date: 2012年11月30日 14:08 | |
This issue is not fixed. Another workaround would be the `win32select` function from twisted: http://twistedmatrix.com/trac/browser/trunk/twisted/internet/selectreactor.py#L23 |
|||
| msg206573 - (view) | Author: Mark Lawrence (BreamoreBoy) * | Date: 2013年12月19日 03:15 | |
Is it worth leaving this open given the arrival of the new asyncio module in Python 3.4? |
|||
| msg219304 - (view) | Author: STINNER Victor (vstinner) * (Python committer) | Date: 2014年05月28日 21:44 | |
This issue was opened 11 years ago, when Windows 95, 98, Me, 2000 and XP were used. Python is going to drop support of Windows XP, and most older versions are already no more supported. Does this issue still exist in recent Windows versions? I'm not aware of such bug. Does asyncio have the bug? |
|||
| msg221750 - (view) | Author: STINNER Victor (vstinner) * (Python committer) | Date: 2014年06月27日 22:40 | |
"Workaround: (...) e = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR)" Oh, it looks like the issue was already fixed 4 years ago: --- changeset: 63720:ba7353147507 branch: 3.1 parent: 63716:915b028b954d user: Giampaolo Rodolà <g.rodola@gmail.com> date: Wed Aug 04 09:04:53 2010 +0000 files: Lib/asyncore.py Misc/ACKS Misc/NEWS description: Merged revisions 83705 via svnmerge from svn+ssh://pythondev@svn.python.org/python/branches/py3k ........ r83705 | giampaolo.rodola | 2010年08月04日 11:02:27 +0200 (mer, 04 ago 2010) | 1 line fix issue #2944: asyncore doesn't handle connection refused correctly (patch by Alexander Shigin). Merged from 2.7 branch. ........ diff -r 915b028b954d -r ba7353147507 Lib/asyncore.py --- a/Lib/asyncore.py Wed Aug 04 04:53:07 2010 +0000 +++ b/Lib/asyncore.py Wed Aug 04 09:04:53 2010 +0000 @@ -426,8 +426,11 @@ class dispatcher: self.handle_read() def handle_connect_event(self): + err = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR) + if err != 0: + raise socket.error(err, _strerror(err)) + self.handle_connect() self.connected = True - self.handle_connect() def handle_write_event(self): if self.accepting: ... --- |
|||
| msg221751 - (view) | Author: STINNER Victor (vstinner) * (Python committer) | Date: 2014年06月27日 22:42 | |
Note: asyncio also calls getsockopt(SOL_SOCKET,SO_ERROR) to check if the connect() succeeded or not, and so it doesn't have this bug. |
|||
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2022年04月10日 16:10:12 | admin | set | github: 38929 |
| 2014年06月27日 22:42:04 | vstinner | set | messages: + msg221751 |
| 2014年06月27日 22:40:49 | vstinner | set | status: open -> closed resolution: fixed messages: + msg221750 |
| 2014年06月06日 11:52:29 | vstinner | set | title: asyncore is broken for windows if connection is refused -> asyncore/Windows: select() doesn't report errors for a non-blocking connect() |
| 2014年06月06日 11:45:21 | vstinner | set | nosy:
+ yselivanov, gvanrossum components: + asyncio |
| 2014年05月28日 21:44:33 | vstinner | set | nosy:
+ vstinner messages: + msg219304 |
| 2014年02月03日 15:41:32 | BreamoreBoy | set | nosy:
- BreamoreBoy |
| 2013年12月19日 19:37:41 | schlamar | set | nosy:
- schlamar |
| 2013年12月19日 03:15:18 | BreamoreBoy | set | nosy:
+ BreamoreBoy messages: + msg206573 |
| 2012年11月30日 14:08:28 | schlamar | set | nosy:
+ schlamar messages: + msg176687 |
| 2009年03月28日 12:18:28 | intgr | set | nosy:
+ intgr |
| 2009年02月13日 23:46:55 | josiahcarlson | set | messages: + msg81978 |
| 2009年02月13日 03:27:42 | ajaksu2 | set | type: behavior superseder: asyncore fixes and improvements messages: + msg81863 components: + Windows nosy: + ajaksu2 |
| 2008年03月20日 00:55:45 | giampaolo.rodola | set | nosy: + giampaolo.rodola |
| 2003年07月25日 14:43:37 | garth42 | create | |