#!/usr/bin/ruby require "socket" $KCODE='u' COMMAND_CODE_ZIP_TO_ADDR = 0x01 COMMAND_CODE_ZIP_TO_ADDR_RESPONSE = 0x02 COMMAND_CODE_ADDR_TO_ZIP = 0x11 COMMAND_CODE_ADDR_TO_ZIP_RESPONSE = 0x12 def resp(code, ver, converted, zip, addr, udp_sock, peer) addr = (addr ? addr.tr("\0", "") : "") #p peer len = 1 + 7 + addr.size + 1 len_h = len / 256 len_l = len % 256 msg = " " * len msg[0] = code msg[1] = ver msg[2] = len_h msg[3] = len_l msg[4] = converted msg[5..11] = zip ? zip : "0000000" msg[12..-1] = addr + "\0" udp_sock.send(msg, 0, peer[3], peer[1]) end def zip_to_addr_ver1(zip, udp_sock, peer) zip_to_addr_map = { "1000004" => "東京都千代田区大手町", } addr = zip_to_addr_map[zip] #puts "#{zip} => #{addr}" resp COMMAND_CODE_ZIP_TO_ADDR_RESPONSE, 1, addr ? 1 : 0, zip, addr, udp_sock, peer end def addr_to_zip_ver1(addr, udp_sock, peer) addr_to_zip_map = { "東京都千代田区大手町" => "1000004", } zip = addr_to_zip_map[addr.tr("\0", "")] #puts "#{addr} => #{zip}" resp COMMAND_CODE_ADDR_TO_ZIP_RESPONSE, 1, zip ? 1 : 0, zip, addr, udp_sock, peer end fntbl = { [ COMMAND_CODE_ZIP_TO_ADDR, 1 ] => method(:zip_to_addr_ver1), [ COMMAND_CODE_ADDR_TO_ZIP, 1 ] => method(:addr_to_zip_ver1), } begin udp_sock = UDPSocket.open() udp_sock.bind("0.0.0.0", 10000) loop do Thread.start(udp_sock.recvfrom(65535)) do |r| msg = r[0] peer = r[1] code = msg[0] ver = msg[1] len_h = msg[2] len_l = msg[3] len = (len_h << 8) + len_l fntbl[[code, ver]].call(msg[4, len], udp_sock, peer) end end rescue ensure udp_sock.close if udp_sock != nil end