diff -urN rt_v19/cg.py rt_v20/cg.py
--- rt_v19/cg.py	2018-04-06 15:33:58.000000000 +0900
+++ rt_v20/cg.py	2018-04-12 21:29:06.000000000 +0900
@@ -15,6 +15,7 @@
 import wf
 import rt
 import dat
+import sock
 
 def if_not_set_opt(d, k, v):
 	ut.if_not_set(d, k, v)
@@ -245,6 +246,13 @@
 
 	data = sum( map( d_setup, dat.data ), [] )
 
+	if 'use_srv' in sys.argv:
+		sock.server_boot( len(data) )
+		sock.client.conn()
+		for (i, d) in enumerate(data):
+			ax_ = d.get('l2g')[0]
+			sock.client.add( i, d.get('kind'), ax_ )
+
 	lights = dat.lights
 
 	(w, h) = ( ut.arg_i('w', 640) , ut.arg_i('h', 480) )
@@ -286,4 +294,6 @@
 		video.show_zm('', wsec)
 		video.clear()
 	video.fin()
+	if 'use_srv' in sys.argv:
+		sock.client.quit()
 # EOF
diff -urN rt_v19/rt.py rt_v20/rt.py
--- rt_v19/rt.py	2018-04-12 09:39:53.000000000 +0900
+++ rt_v20/rt.py	2018-04-12 21:29:06.000000000 +0900
@@ -10,6 +10,7 @@
 import lstx
 import cross
 import img
+import sock
 
 def map_col(crs, rev, video):
 	d = crs.get('d')
@@ -41,16 +42,27 @@
 
 ref_rate = ut.arg_f('ref_rate', 0.001)
 
+use_srv = 'use_srv' in sys.argv
+
 def get_col(data, lights, l_g, video, nest_rate=1.0, prev_d=None):
 	if nest_rate < 0.01:
 		return []
 
-	lst = map( lambda d: { 'l_g': l_g, 'd': d, 'eq_d': d == prev_d }, data )
-	lst = ut.filter_lst( lambda crs: cross.cross(crs), lst )
-	if not lst:
-		return []
-
-	crs = min( lst, key=lambda crs: crs.get('t') )
+	crs = {}
+	if use_srv:
+		prev_idx = data.index(prev_d) if prev_d else -1
+		(i, t) = sock.client.cross(l_g, prev_idx)
+		if i < 0:
+			return []
+		crs['d'] = d = data[i]
+		crs['t'] = t
+		crs['l'] = lstx.tr_line( d.get('l2g'), 'g2l', l_g )
+	else:
+		lst = map( lambda d: { 'l_g': l_g, 'd': d, 'eq_d': d == prev_d }, data )
+		lst = ut.filter_lst( lambda crs: cross.cross(crs), lst )
+		if not lst:
+			return []
+		crs = min( lst, key=lambda crs: crs.get('t') )
 
 	cross.nv(crs)
 
diff -urN rt_v19/sock.py rt_v20/sock.py
--- rt_v19/sock.py	1970-01-01 09:00:00.000000000 +0900
+++ rt_v20/sock.py	2018-04-12 21:28:46.000000000 +0900
@@ -0,0 +1,195 @@
+#!/usr/bin/env python
+
+import sys
+import subprocess
+import numpy as np
+import struct
+import socket
+import six
+import ut
+import line
+import vecs
+import ax
+import cross
+
+HOST = 'localhost'
+PORT = ut.arg_i('port', 23456)
+
+kinds = [ 'square', 'circle', 'triangle', 'ball', 'pipe_side', 'cone_side' ]
+		
+pack_i4 = lambda i: struct.pack('=i', i)
+pack_np64 = lambda np64_arr: np64_arr.tobytes() if six.PY3 else bytes( np.getbuffer(np64_arr) )
+
+unpack_i4 = lambda s: ( struct.unpack_from('=i', s)[0], s[4:] )
+unpack_np64 = lambda s, n: ( np.frombuffer( s[:8*n], dtype=np.float64 ), s[8*n:] )
+
+def new_client():
+	e = ut.Empty()
+	e.proc = None
+	e.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+	e.conn = lambda : e.sock.connect((HOST, PORT))
+
+	def send_recv(s, rn):
+		e.sock.sendall(s)
+		return e.sock.recv(rn) if rn > 0 else ''
+
+	def quit():
+		send_recv(b'q', 1)
+		ut.kill_proc(e.proc)
+		ut.cmd_exec('rm fifo')
+	e.quit = quit
+
+	e.clear = lambda : send_recv(b'c', 0)
+
+	def add(i, kind, ax):
+		s = b'a'
+		s += pack_i4(i)
+		s += pack_i4( kinds.index(kind) )
+		s += pack_np64(ax.p)
+		s += pack_np64(ax.vs.v3)
+		send_recv(s, 0)
+	e.add = add
+
+	def cross(l_g, prev_idx=-1):
+		s = b'x'
+		s += pack_np64(l_g.p)
+		s += pack_np64(l_g.v)
+		s += pack_i4(prev_idx)
+
+		s = send_recv(s, 4+8)
+
+		(i, s) = unpack_i4(s)
+		(t, s) = unpack_np64(s, 1)
+		return ( i, t[0] )
+	e.cross = cross
+
+	return e
+
+client = new_client()
+
+###
+
+def server_boot(n=100):
+	cmd1 = 'nc -l {}'.format(PORT)
+	cmd2 = './sock.py n={} xname={}'.format( n, ut.arg_s('xname', 'xdat') )
+	cmd = 'rm -f fifo ; mkfifo fifo ; cat fifo | {} | {} > fifo'.format(cmd1, cmd2)
+	client.proc = ut.cmd_proc(cmd)
+	ut.sleep(3.0) #
+
+def new_server():
+	e = ut.Empty()
+	e.data = []
+
+	def alloc(n):
+		e.data = []
+		for i in range(n):
+			e.data.append({})
+
+	clear = lambda : alloc( len(e.data) )
+
+	recv = lambda n: sys.stdin.buffer.read(n) if six.PY3 else sys.stdin.read(n)
+
+	def send(s):
+		if six.PY3:
+			sys.stdout.buffer.write(s)
+		else:
+			sys.stdout.write(s)
+		sys.stdout.flush()
+
+	err_msg = lambda s: sys.stderr.write(s + '\n')
+
+	def add():
+		s = recv( 4 + 4 + 8*3 + 8*3*3 )
+		(i, s) = unpack_i4(s)
+		(ki, s) = unpack_i4(s)
+		(p, s) = unpack_np64(s, 3)
+		(v3, s) = unpack_np64(s, 3*3)
+		d = e.data[i]
+		d['kind'] = kinds[ki]
+		d['l2g'] = [ ax.new( p, vecs.new( v3.reshape(3,3) ) ) ]
+	
+	e.in_ = []
+	e.out = []
+
+	def cross_():
+		s = recv(8*3 + 8*3 + 4)
+
+		if e.in_:
+			send( e.in_.pop(0) )
+			return
+
+		(p, s) = unpack_np64(s, 3)
+		(v, s) = unpack_np64(s, 3)
+		(prev_idx, s) = unpack_i4(s)
+		l_g = line.new(p, v)
+
+		lst = []
+		for (i, d) in enumerate(e.data):
+			if not d:
+				continue
+			crs = { 'l_g': l_g, 'd': d, 'eq_d': i == prev_idx }
+			if not cross.cross(crs):
+				continue
+			crs['idx'] = i
+			lst.append(crs)
+		idx = -1
+		t = np.float64(0)
+		if lst:
+			crs = min( lst, key=lambda crs: crs.get('t') )
+			idx = crs.get('idx')
+			t = crs.get('t')
+		s = pack_i4(idx) + pack_np64(t)
+		send(s)
+		e.out.append(s)
+
+	e.fn = ut.arg_s('xname', 'xdat')
+
+	def save():
+		if not e.out or ut.exists(e.fn):
+			return
+		with open(e.fn, 'wb') as f:
+			s = b''.join(e.out)
+			f.write(s)
+
+	def load():
+		if not ut.exists(e.fn):
+			return
+		with open(e.fn, 'rb') as f:
+			s = f.read()
+		usz = 4+8
+		e.in_ = []
+		while s:
+			e.in_.append( s[:usz] )
+			s = s[usz:]
+
+	def quit():
+		save()
+		send(b'r')
+		sys.exit(0)
+
+	def main_loop():
+		alloc( ut.arg_i('n', 100) )
+		load()
+		while True:
+			cmd = recv(1)
+			f = {
+				b'c': clear,
+				b'a': add,
+				b'x': cross_,
+				b'q': quit,
+			}.get(cmd)
+			if f:
+				f()
+			else:
+				msg = '?' + ( ' cmd={:02x}' if cmd else '' )
+				err_msg(msg)
+				sys.exit(1)
+	e.main_loop = main_loop
+
+	return e
+
+server = new_server()
+
+if __name__ == "__main__":
+	server.main_loop()
+# EOF
diff -urN rt_v19/ut.py rt_v20/ut.py
--- rt_v19/ut.py	2018-04-07 23:48:39.000000000 +0900
+++ rt_v20/ut.py	2018-04-12 21:28:50.000000000 +0900
@@ -3,6 +3,7 @@
 import sys
 import os
 import time
+import signal
 import subprocess
 from decimal import *
 
@@ -173,6 +174,23 @@
 		return subprocess.check_output(cmd, shell=True)
 	except:
 		return ''
+
+def cmd_proc(cmd):
+	try:
+		return subprocess.Popen( cmd, shell=True, preexec_fn=os.setsid )
+	except:
+		return None
+
+def is_alive(proc):
+	if not proc:
+		return False
+	proc.poll()
+	return proc.returncode == None
+
+def kill_proc(proc, sig=signal.SIGKILL):
+	if proc and is_alive(proc):
+		os.killpg(proc.pid, sig)
+
 ###
 
 exists = lambda path: os.path.exists(path)
