在eiffel中通过网络进行控制台应用?

时间:2013-11-28 22:41:51

标签: sockets eiffel

嘿我在项目中工作,但我无法通过不在同一网络(LAN)中的IP进行连接。代码bellow在本地工作正常,但我无法弄清楚如何从位于不同位置的不同IP进行工作?并且google无法看到帮助,任何想法?

   class
    RG_NETWORK_SERVER

inherit
    STORABLE
    NETWORK_SERVER
        redefine
            receive,
            received,
            close
        end

create
    make_server

feature
    connections: LINKED_LIST [RG_CONNECTION]
    max_to_poll: INTEGER
    message_out: RG_MESSAGE
    received: detachable RG_MESSAGE
    poll: MEDIUM_POLLER

    make_server
        require

        local
            l_message_out: detachable like message_out
            l_connections: detachable like connections
            l_in: detachable like in
        do
            make (1337)
            max_to_poll := 1
            create poll.make_read_only
            in.set_non_blocking
            l_in := in
            create l_message_out.make
            message_out := l_message_out
            create l_connections.make
            connections := l_connections
            connections.compare_objects
            execute
        end

    process_message
        local
            stop: BOOLEAN
            pos: INTEGER
        do
            from
                connections.start
            until
                connections.after or stop
            loop
                if connections.item.is_waiting then
                    if attached {RG_MESSAGE} retrieved (connections.item.active_medium) as l_message_in then
                        if l_message_in.new then
                            connections.item.set_client_name (l_message_in.client_name)
                            create message_out.make
                            message_out.set_client_name (l_message_in.client_name)
                            message_out.extend (l_message_in.client_name)
                            message_out.extend (" has just joined the server%N")
                        elseif l_message_in.over then
                            poll.remove_associated_read_command (connections.item.active_medium)
                            connections.remove
                            create message_out.make
                            message_out.set_client_name (l_message_in.client_name)
                            message_out.extend (l_message_in.client_name)
                            message_out.extend (" has just gone%N")
                            stop := True
                        else
                            message_out := l_message_in.deep_twin
                            message_out.put_front (" has just sent that :%N")
                            message_out.put_front (message_out.client_name)
                            message_out.put_front ("-> ")
                        end
                        pos := connections.index
                            -- l_message_in.print_message
                        message_out.print_message
                        broadcast
                        connections.go_i_th (pos)

                            -- Post status to client
                        create message_out.make
                        message_out.extend ("Got it! %N")
                        message_out.independent_store (connections.item.active_medium)
                    end
                end
                if not stop then
                    connections.forth
                end
            end
        end

    broadcast
        local
            client_name: detachable STRING
        do
            client_name := message_out.client_name
            if client_name /= Void then
                from
                    connections.start
                until
                    connections.after
                loop
                    if connections.item.client_name /~ client_name then
                        message_out.independent_store (connections.item.active_medium)
                    end
                    connections.forth
                end
            end
        end

    receive
        do
            in.accept
            if attached {like outflow} in.accepted as l_outflow then
                l_outflow.set_blocking
                new_client (l_outflow)
            end
            from
                connections.start
            until
                connections.after
            loop
                connections.item.initialize
                connections.forth
            end
            poll.execute (max_to_poll, 1000)
        end

    new_client (a_flow: attached like outflow)
        local
            new_connection: RG_CONNECTION
        do
            if max_to_poll <= a_flow.descriptor then
                max_to_poll := a_flow.descriptor + 1
            end
            create new_connection.make (a_flow)
            connections.extend (new_connection)
            create message_out.make
            message_out.extend ("Welcome! %N")
            message_out.independent_store (a_flow)
            poll.put_read_command (new_connection)
        end

end

和客户:

class
    RG_NETWORK_CLIENT

inherit
    NETWORK_CLIENT
        redefine
            received
        end

create
    make_join

feature
    make_join(ip:STRING)
        require
            is_ip_void : ip /= Void
        local
        l_client_name: detachable like client_name
        do
            check_name
            l_client_name := client_name
            make (1337, ip)
            max_to_poll := in_out.descriptor + 1
            create connection.make (in_out)
            create poll.make_read_only
            poll.put_read_command (connection)
            send_name_to_server
            auto_scan_server
            processing
        end

feature

    connection: RG_CONNECTION
    std_input: detachable RG_CONNECTION
    message_out: RG_MESSAGE
    received: detachable RG_MESSAGE
    client_name: STRING
    over: BOOLEAN
    poll: MEDIUM_POLLER
    input_poll: detachable MEDIUM_POLLER
    max_to_poll: INTEGER
    waiting:BOOLEAN

    send_name_to_server
        do
            create message_out.make
            message_out.set_client_name (client_name)
            message_out.set_new (True)
            message_out.set_over (False)
            send (message_out)
        end

    processing
        do
            from
                over := False
            until
                over
            loop
                scan_from_server
                if not over then
                    read_content
                end
            end
            cleanup
        end

    read_content
        local
            temp: detachable STRING
        do
            io.put_string ("Enter message: ")
            io.readline
            temp := io.laststring
            if temp /= Void and not temp.is_empty then
                if temp.is_equal ("bye") then
                    over := True
                end
                create message_out.make
                message_out.extend (temp)
                message_out.extend ("%N")
                message_out.set_over (over)
                message_out.set_client_name (client_name)
                message_out.set_new (False)
                send (message_out)
                auto_scan_server
            end
        end

    check_name
        local
            l_name: detachable STRING
        do
            io.putstring ("Enter your name : ")
            io.readline
            l_name := io.laststring
            check
                l_name_attached: l_name /= Void
            end
            client_name := l_name.twin
        end

    scan_from_server
        local
            l_received: like received
        do
            connection.initialize
            poll.execute (max_to_poll, 1000)
            if connection.is_waiting then
                receive
                l_received := received
                if l_received /= Void then
                    waiting := FALSE
                    l_received.print_message
                    if l_received.over then
                        over := True
                    end
                end
            end
        end

    auto_scan_server
        do
            waiting := True
            from until not waiting
            loop
                scan_from_server
            end
        end

end

1 个答案:

答案 0 :(得分:0)

解决方法是使用Eiffel提供的样本进行工作,它是两个人在同一网络中连接的最长时间。例如如下:

在这里,我们定义用户是否已收到消息或正在等待消息,还重新定义poll_command以便能够使用它。

inherit

    POLL_COMMAND
        redefine
            make
        end

create
    make

feature {NONE} -- Initialization

    make (s: IO_MEDIUM)
        do
            Precursor (s)
            create client_name.make_empty
        end

feature

    is_waiting: BOOLEAN
    client_name: STRING

    execute (arg: ANY)
        do
            is_waiting := True
        end

    initialize
        do
            is_waiting := False
        end

    set_client_name (s: STRING)
        require
            s_exists: s /= Void
        do
            client_name := s.twin
        end

end 

然后按照聊天示例,可以在samples文件夹中找到,在消息处理程序中,我们创建了以下内容:

set_client_name (s: STRING)
        require
            s_not_void: s /= Void
        do
            client_name := s.twin
        end

    set_new (flag: BOOLEAN)
        do
            new := flag
        end

稍后在连接类中,我们可以连接到服务器ip,它可以通过true命令行或通过GUI输入。

make_join (name: STRING; ip: STRING; gc: RG_CLIENT)
        require
            is_ip_void: ip /= Void
        do
                -- Connects to IP on port 1337
            make (1337, ip)
            max_to_poll := in_out.descriptor + 1
            create connection.make (in_out)
            create poll.make_read_only
            poll.put_read_command (connection)
                -- Sets client name and refrence
            client_name := name
            p_client := gc
                -- Sends name to server and receives ID
            client_id := send_name_to_server
                -- Launches instance as thread
            make_thread
            launch
            execute
        end

然后在服务器类中......

make_server (gs: RG_SERVER)
        local
            l_message_out: detachable like message_out
            l_connections: detachable like connections
            l_in: detachable like in
        do
                -- Instantiate reference and create server listening on port 1337
            game_server := gs
            make (1337)
            max_to_poll := 1
            create poll.make_read_only
            in.set_non_blocking
            l_in := in
            create l_connections.make
            connections := l_connections
            connections.compare_objects
                -- Launches instance as tread
            make_thread
            launch
        end

还有更多的代码,但这是一个很好的示例,如何做到这一点,必须有一个方法来处理连接,但这是一个良好的开端,还要记住所有这些都是基于他们的样本,聊天样本是一个很好的开始..

在没有崩溃的情况下享受埃菲尔。