diff --git a/netrender/client.py b/netrender/client.py
index ebc9824c6bbe249dbe9b9d058899bb1a346df678..b992f37d914643e708ad0fe9f65ce760dbbc5061 100644
--- a/netrender/client.py
+++ b/netrender/client.py
@@ -157,7 +157,8 @@ def clientSendJobVCS(conn, scene, anim = False):
     job.version_info.revision = netsettings.vcs_revision
 
     # try to send path first
-    conn.request("POST", "/job", json.dumps(job.serialize()))
+    with ConnectionContext():
+        conn.request("POST", "/job", json.dumps(job.serialize()))
     response = conn.getresponse()
     response.read()
 
@@ -240,7 +241,8 @@ def clientSendJobBlender(conn, scene, anim = False):
     fillCommonJobSettings(job, job_name, netsettings)
 
     # try to send path first
-    conn.request("POST", "/job", json.dumps(job.serialize()))
+    with ConnectionContext():
+        conn.request("POST", "/job", json.dumps(job.serialize()))
     response = conn.getresponse()
     response.read()
 
@@ -250,7 +252,8 @@ def clientSendJobBlender(conn, scene, anim = False):
     if response.status == http.client.ACCEPTED:
         for rfile in job.files:
             f = open(rfile.filepath, "rb")
-            conn.request("PUT", fileURL(job_id, rfile.index), f)
+            with ConnectionContext():
+                conn.request("PUT", fileURL(job_id, rfile.index), f)
             f.close()
             response = conn.getresponse()
             response.read()
@@ -260,7 +263,8 @@ def clientSendJobBlender(conn, scene, anim = False):
     return job_id
 
 def requestResult(conn, job_id, frame):
-    conn.request("GET", renderURL(job_id, frame))
+    with ConnectionContext():
+        conn.request("GET", renderURL(job_id, frame))
 
 class NetworkRenderEngine(bpy.types.RenderEngine):
     bl_idname = 'NET_RENDER'
@@ -333,7 +337,8 @@ class NetworkRenderEngine(bpy.types.RenderEngine):
 
             # cancel new jobs (animate on network) on break
             if self.test_break() and new_job:
-                conn.request("POST", cancelURL(job_id))
+                with ConnectionContext():
+                    conn.request("POST", cancelURL(job_id))
                 response = conn.getresponse()
                 response.read()
                 print( response.status, response.reason )
diff --git a/netrender/operators.py b/netrender/operators.py
index da5f7046401aea9112e339de751c40ccc172e016..3f27bd7125960254eaf268dafd52e39aedb0d685 100644
--- a/netrender/operators.py
+++ b/netrender/operators.py
@@ -201,8 +201,8 @@ class RENDER_OT_netclientstatus(bpy.types.Operator):
         conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report)
 
         if conn:
-            conn.request("GET", "/status")
-
+            with ConnectionContext():
+                conn.request("GET", "/status")
             response = conn.getresponse()
             content = response.read()
             print( response.status, response.reason )
@@ -229,7 +229,7 @@ class RENDER_OT_netclientstatus(bpy.types.Operator):
         return self.execute(context)
 
 class RENDER_OT_netclientblacklistslave(bpy.types.Operator):
-    '''Exclude from rendering, by adding slave to the blacklist.'''
+    '''Exclude from rendering, by adding slave to the blacklist'''
     bl_idname = "render.netclientblacklistslave"
     bl_label = "Client Blacklist Slave"
 
@@ -259,7 +259,7 @@ class RENDER_OT_netclientblacklistslave(bpy.types.Operator):
         return self.execute(context)
 
 class RENDER_OT_netclientwhitelistslave(bpy.types.Operator):
-    '''Remove slave from the blacklist.'''
+    '''Remove slave from the blacklist'''
     bl_idname = "render.netclientwhitelistslave"
     bl_label = "Client Whitelist Slave"
 
@@ -303,8 +303,8 @@ class RENDER_OT_netclientslaves(bpy.types.Operator):
         conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report)
 
         if conn:
-            conn.request("GET", "/slaves")
-
+            with ConnectionContext():
+                conn.request("GET", "/slaves")
             response = conn.getresponse()
             content = response.read()
             print( response.status, response.reason )
@@ -341,7 +341,7 @@ class RENDER_OT_netclientslaves(bpy.types.Operator):
         return self.execute(context)
 
 class RENDER_OT_netclientcancel(bpy.types.Operator):
-    '''Cancel the selected network rendering job.'''
+    '''Cancel the selected network rendering job'''
     bl_idname = "render.netclientcancel"
     bl_label = "Client Cancel"
 
@@ -357,8 +357,8 @@ class RENDER_OT_netclientcancel(bpy.types.Operator):
         if conn:
             job = netrender.jobs[netsettings.active_job_index]
 
-            conn.request("POST", cancelURL(job.id), json.dumps({'clear':False}))
-
+            with ConnectionContext():
+                conn.request("POST", cancelURL(job.id), json.dumps({'clear':False}))
             response = conn.getresponse()
             response.read()
             print( response.status, response.reason )
@@ -371,7 +371,7 @@ class RENDER_OT_netclientcancel(bpy.types.Operator):
         return self.execute(context)
 
 class RENDER_OT_netclientcancelall(bpy.types.Operator):
-    '''Cancel all running network rendering jobs.'''
+    '''Cancel all running network rendering jobs'''
     bl_idname = "render.netclientcancelall"
     bl_label = "Client Cancel All"
 
@@ -384,8 +384,8 @@ class RENDER_OT_netclientcancelall(bpy.types.Operator):
         conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report)
 
         if conn:
-            conn.request("POST", "/clear", json.dumps({'clear':False}))
-
+            with ConnectionContext():
+                conn.request("POST", "/clear", json.dumps({'clear':False}))
             response = conn.getresponse()
             response.read()
             print( response.status, response.reason )
@@ -416,10 +416,10 @@ class netclientdownload(bpy.types.Operator):
         if conn:
             job_id = netrender.jobs[netsettings.active_job_index].id
     
-            conn.request("GET", "/status", headers={"job-id":job_id})
-    
+            with ConnectionContext():
+                conn.request("GET", "/status", headers={"job-id":job_id})
             response = conn.getresponse()
-            
+        
             if response.status != http.client.OK:
                 self.report({'ERROR'}, "Job ID %i not defined on master" % job_id)
                 return {'ERROR'}
@@ -486,7 +486,7 @@ class netclientdownload(bpy.types.Operator):
         return self.execute(context)
 
 class netclientscan(bpy.types.Operator):
-    '''Listen on network for master server broadcasting its address and port.'''
+    '''Listen on network for master server broadcasting its address and port'''
     bl_idname = "render.netclientscan"
     bl_label = "Client Scan"
 
diff --git a/netrender/slave.py b/netrender/slave.py
index 6fef4f4e4ecbe57e8a3500b16c5339cee277664b..6ae0982965468d839edf5c5da8411a4eeb39ae39 100644
--- a/netrender/slave.py
+++ b/netrender/slave.py
@@ -67,7 +67,8 @@ def slave_Info():
     return slave
 
 def testCancel(conn, job_id, frame_number):
-        conn.request("HEAD", "/status", headers={"job-id":job_id, "job-frame": str(frame_number)})
+        with ConnectionContext():
+            conn.request("HEAD", "/status", headers={"job-id":job_id, "job-frame": str(frame_number)})
 
         # canceled if job isn't found anymore
         if responseStatus(conn) == http.client.NO_CONTENT:
@@ -93,7 +94,8 @@ def testFile(conn, job_id, slave_id, rfile, JOB_PREFIX, main_path = None):
         # Force prefix path if not found
         job_full_path = prefixPath(JOB_PREFIX, rfile.filepath, main_path, force = True)
         temp_path = os.path.join(JOB_PREFIX, "slave.temp")
-        conn.request("GET", fileURL(job_id, rfile.index), headers={"slave-id":slave_id})
+        with ConnectionContext():
+            conn.request("GET", fileURL(job_id, rfile.index), headers={"slave-id":slave_id})
         response = conn.getresponse()
 
         if response.status != http.client.OK:
@@ -155,7 +157,8 @@ def render_slave(engine, netsettings, threads):
             print("Retry %i failed, waiting %is before retrying" % (i + 1, bisleep.current))
     
     if conn:
-        conn.request("POST", "/slave", json.dumps(slave_Info().serialize()))
+        with ConnectionContext():
+            conn.request("POST", "/slave", json.dumps(slave_Info().serialize()))
         response = conn.getresponse()
         response.read()
 
@@ -168,7 +171,8 @@ def render_slave(engine, netsettings, threads):
         engine.update_stats("", "Network render connected to master, waiting for jobs")
 
         while not engine.test_break():
-            conn.request("GET", "/job", headers={"slave-id":slave_id})
+            with ConnectionContext():
+                conn.request("GET", "/job", headers={"slave-id":slave_id})
             response = conn.getresponse()
 
             if response.status == http.client.OK:
@@ -218,7 +222,8 @@ def render_slave(engine, netsettings, threads):
 
                 # announce log to master
                 logfile = netrender.model.LogFile(job.id, slave_id, [frame.number for frame in job.frames])
-                conn.request("POST", "/log", bytes(json.dumps(logfile.serialize()), encoding='utf8'))
+                with ConnectionContext():
+                    conn.request("POST", "/log", bytes(json.dumps(logfile.serialize()), encoding='utf8'))
                 response = conn.getresponse()
                 response.read()
 
@@ -258,7 +263,8 @@ def render_slave(engine, netsettings, threads):
                         # update logs if needed
                         if stdout:
                             # (only need to update on one frame, they are linked
-                            conn.request("PUT", logURL(job.id, first_frame), stdout, headers=headers)
+                            with ConnectionContext():
+                                conn.request("PUT", logURL(job.id, first_frame), stdout, headers=headers)
                             responseStatus(conn)
                             
                             # Also output on console
@@ -293,7 +299,9 @@ def render_slave(engine, netsettings, threads):
                         print(str(stdout, encoding='utf8'), end="")
                     
                     # (only need to update on one frame, they are linked
-                    conn.request("PUT", logURL(job.id, first_frame), stdout, headers=headers)
+                    with ConnectionContext():
+                        conn.request("PUT", logURL(job.id, first_frame), stdout, headers=headers)
+                    
                     if responseStatus(conn) == http.client.NO_CONTENT:
                         continue
 
@@ -323,18 +331,21 @@ def render_slave(engine, netsettings, threads):
                                 
                                 if thumbname:
                                     f = open(thumbname, 'rb')
-                                    conn.request("PUT", "/thumb", f, headers=headers)
+                                    with ConnectionContext():
+                                        conn.request("PUT", "/thumb", f, headers=headers)
                                     f.close()
                                     responseStatus(conn)
 
                             f = open(filename, 'rb')
-                            conn.request("PUT", "/render", f, headers=headers)
+                            with ConnectionContext():
+                                conn.request("PUT", "/render", f, headers=headers)
                             f.close()
                             if responseStatus(conn) == http.client.NO_CONTENT:
                                 continue
 
                         elif job.type == netrender.model.JOB_PROCESS:
-                            conn.request("PUT", "/render", headers=headers)
+                            with ConnectionContext():
+                                conn.request("PUT", "/render", headers=headers)
                             if responseStatus(conn) == http.client.NO_CONTENT:
                                 continue
                 else:
@@ -342,7 +353,8 @@ def render_slave(engine, netsettings, threads):
                     for frame in job.frames:
                         headers["job-frame"] = str(frame.number)
                         # send error result back to server
-                        conn.request("PUT", "/render", headers=headers)
+                        with ConnectionContext():
+                            conn.request("PUT", "/render", headers=headers)
                         if responseStatus(conn) == http.client.NO_CONTENT:
                             continue
 
diff --git a/netrender/utils.py b/netrender/utils.py
index 1ae60a20a0703781887241462cdc5444e66ee5a7..5b8e1995aeae7cb4cd28719e629dcde9d3122303 100644
--- a/netrender/utils.py
+++ b/netrender/utils.py
@@ -16,7 +16,7 @@
 #
 # ##### END GPL LICENSE BLOCK #####
 
-import sys, os, re
+import sys, os, re, platform
 import http, http.client, http.server, socket
 import subprocess, time, hashlib
 
@@ -57,6 +57,30 @@ FRAME_STATUS_TEXT = {
         ERROR: "Error"
         }
 
+if platform.system() == "Darwin":
+    class ConnectionContext:
+        def __init__(self, timeout = None):
+            self.old_timeout = socket.getdefaulttimeout()
+            self.timeout = timeout
+            
+        def __enter__(self):
+            if self.old_timeout != self.timeout:
+                socket.setdefaulttimeout(self.timeout)
+        def __exit__(self, exc_type, exc_value, traceback):
+            if self.old_timeout != self.timeout:
+                socket.setdefaulttimeout(self.old_timeout)
+else:
+    # On sane OSes we can use the connection timeout value correctly
+    class ConnectionContext:
+        def __init__(self, timeout = None):
+            pass
+            
+        def __enter__(self):
+            pass
+
+        def __exit__(self, exc_type, exc_value, traceback):
+            pass
+
 class DirectoryContext:
     def __init__(self, path):
         self.path = path
@@ -146,7 +170,11 @@ def clientConnection(address, port, report = None, scan = True, timeout = 5):
             return None
 
     try:
-        conn = http.client.HTTPConnection(address, port, timeout = timeout)
+        if platform.system() == "Darwin":
+            with ConnectionContext(timeout):
+                conn = http.client.HTTPConnection(address, port)
+        else:
+            conn = http.client.HTTPConnection(address, port, timeout = timeout)
 
         if conn:
             if clientVerifyVersion(conn):
@@ -163,7 +191,8 @@ def clientConnection(address, port, report = None, scan = True, timeout = 5):
             return None
 
 def clientVerifyVersion(conn):
-    conn.request("GET", "/version")
+    with ConnectionContext():
+        conn.request("GET", "/version")
     response = conn.getresponse()
 
     if response.status != http.client.OK: