こんにちは、shelarcy です。

この間から SML のプログラムの移植に取り組んでいるのですが、これ
まで Network Programming をした事がないこともあってか、API 間の
溝の大きさに行き詰まってしまいました。

何か良いアドバイスがありましたら、御教示の程宜しくお願いします。


fun spawnNetServer (myPort, startId, tsMb, addTS) = let
       val mySock = INetSock.TCP.socket()
       fun loop nextId = let
             val (newSock, addr) = Socket.accept mySock
             val proxyConn = spawnBuffers (nextId, newSock, tsMb)
             val (host, port) = INetSock.fromAddr addr
             val name = (case NetHostDB.getByAddr host
                    of (SOME ent) => NetHostDB.name ent
                    | NONE => "??"
                    (* end case *))
             in
               addTS {name = name, id = nextId, conn = proxyConn};
               loop (nextId + 1)
             end
       val port = getOpt(myPort, 7001)
       in
         Socket.bind (mySock, INetSock.any port);
         Socket.listen (mySock, 5);
         spawn (fn () => loop startId);
         NETWORK{shutdown = SyncVar.iVar()}
       end

fun initNetwork {port, remote, tsReqMb, addTS} = let
       val hosts = List.map parseHost remote
       val startId = length hosts + 1
       val network = spawnNetServer (port, startId, tsReqMb, addTS)
       val mkServer ({host, addr, port), (id, l))
             val sock = INetSock.TCP.socket()
             val sockAddr = INetSock.toAddr(addr, port)
             val _ = Socket.connect (sock, sockAddr)
             val conn =  spawnBuffers (id, sock, tsReqMb)
             in
               (id+1, {name = host, id = id, conn =conn}::l)
             end
       in
         { myId =0, network = network,
           server = #2 (List.foldl mkServer (1, []) hosts)
         }
       end


fun parseHost h = (case (StringCvt.scanstring SockUtil.scanAddr H)
        of NONE -> error "bad hostname format"
         | (SOME info) => (case SockUtil.resolveAddr info
              of {host, addr, port = NONE} =>
                    {host = host, addr = addr, port = 7001}
               | {host = host, addr, port =p} =>
                   {host =host, addr = addr, port = p}
              (* end case *))
               handle (SockUtil.BadAddr msg) => error msg
         (* end case *))


signature NETWORK =
   sig
     type network
     type server_conn
     eqtype ts_id

     type reply = {transId : int, vals : Tuple.val_atom list}

     datatype client_req
       = OutTuple of Tuple.tuple
       | InReq of {
           from : ts_id.
           transId : int.
           remove : bool
           pat : Tuple.template,
           reply : reply -> unit
         }
       | Accept of {from : ts_id, transId : int}
       | Cancel of {from : ts_id, transId : int}

     type remote_server_info = {
             name : string,
             id : ts_id,
             conn : server_conn
           }

     val initNetwork : {
             port    : int option,
             remote  : string list,
             tsReqMb : client_req Mailbox.mbox,
             addTS   : remot_server_info -> unit
           } ->  {
             myId    : ts_id,
             network : network,
             servers : remot_server_info list
           }

     val sendOutTuple : server_conn -> Tuple.tuple -> unit
     val SendInReq : server_conn -> {
             transId :int,
             remove : bool,
             pat : Tuple.template
           } -> unit
     val sendAccept   : server_conn -> {transId : int } -> unit
     val sendCancel   : server_conn -> {transId : int } -> unit
     val replyEvt     : server_conn -> reply event

     va; shutdown : network -> unit

end (* NETWORK *)



-- 
shelarcy <shelarcy / capella.freemail.ne.jp>
http://page.freett.com/shelarcy/ 

--
ML: haskell-jp / quickml.com
使い方: http://QuickML.com/