<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    上善若水
    In general the OO style is to use a lot of little objects with a lot of little methods that give us a lot of plug points for overriding and variation. To do is to be -Nietzsche, To bei is to do -Kant, Do be do be do -Sinatra
    posts - 146,comments - 147,trackbacks - 0
    在看Jetty源碼中的EndPointTest類,對EndPoint的測試,我的思路是:
    1. 建立一個連接(創建ServerSocket實例,一般還會給定一個端口,其實可以bind(null)以讓操作系統分配一個可用端口),新啟動一個線程,在新線程中監聽給定端口(調用accept方法)。
    2. 發送客戶端請求(創建一個Socket實例,并向該Socket寫入請求數據)。
    3. 在接收端讀取數據,驗證寫入的請求和接收到的數據相同。

    在以上流程實現中,accept方法返回的接收端Socket需要傳給主線程,同時要保證使用該Socket是在accept方法返回之后,以我習慣,我會使用一個Lock或CountDownLatch:
    private static class SocketHolder {
        Socket socket;
    }

    @Test
    public void levinOldWayTest() throws Exception {
        final ServerSocket server = new ServerSocket(10240);
        
        final CountDownLatch latch = new CountDownLatch(1);
        final SocketHolder socketHolder = new SocketHolder();
        new Thread() {
            public void run() {
                try {
                    socketHolder.socket = server.accept();
                    latch.countDown();
                } catch(Exception ex) {
                    ex.printStackTrace();
                }
            }
        }.start();
        
        Socket socket = new Socket(server.getInetAddress(), server.getLocalPort());
        socket.getOutputStream().write("My Test String".getBytes());
        
        latch.await(5, TimeUnit.SECONDS);
        byte[] receives = new byte[4096];
        int length = socketHolder.socket.getInputStream().read(receives);
        
        assertEquals("My Test String", new String(receives, 0, length));
        
        socket.close();
        socketHolder.socket.close();
        server.close();
    }

    不知道有多少人也像我一樣把這段代碼寫成這樣?這里有兩個問題:
    1. ServerSocket的監聽的端口不一定是可用的,類似測試代碼我之前沒有寫過,我估計自己正真在寫的時候應該會想到讓操作系統動態分配。
    2. 為了在兩個線程中傳遞數據,這里首先創建了一個SocketHolder類,然后使用CountDownLatch,寫起來好麻煩。為了簡化這段代碼,可以使用Exchanger,即當一個生產者線程準備好數據后可以通過Exchanger將數據傳遞給消費者,而消費者在生產者傳遞過來數據后就可以消費了,這里的數據就是Socket。

    改進后的代碼如下:
    @Test
    public void levinImprovedWayTest() throws Exception {
        final ServerSocket server = new ServerSocket();
        server.bind(null);
        
        final Exchanger<Socket> exchanger = new Exchanger<Socket>();
        new Thread() {
            public void run() {
                try {
                    exchanger.exchange(server.accept());
                } catch(Exception ex) {
                    ex.printStackTrace();
                }
            }
        }.start();
        
        Socket socket = new Socket(server.getInetAddress(), server.getLocalPort());
        socket.getOutputStream().write("My Test String".getBytes());
        
        Socket receiverSocket = exchanger.exchange(null, 5, TimeUnit.SECONDS);
        byte[] receives = new byte[4096];
        int length = receiverSocket.getInputStream().read(receives);
        
        assertEquals("My Test String", new String(receives, 0, length));
        
        socket.close();
        receiverSocket.close();
        server.close();
    }
    posted on 2014-03-23 13:40 DLevin 閱讀(1484) 評論(0)  編輯  收藏 所屬分類: Core Java
    主站蜘蛛池模板: 久久被窝电影亚洲爽爽爽| 国产精品成人无码免费| 精品亚洲综合久久中文字幕| 免费人成动漫在线播放r18| 国产大片线上免费看| 亚洲av无码偷拍在线观看| 色播在线永久免费视频| 国产亚洲精品免费| 免费人妻无码不卡中文字幕18禁| 老司机精品视频免费| 久久精品亚洲福利| 暖暖免费日本在线中文| 亚洲黄色在线视频| 无限动漫网在线观看免费| 亚洲中文字幕久久精品蜜桃| 国产高清在线免费视频| 成人福利在线观看免费视频| 亚洲一区二区三区无码中文字幕| 黄网站色视频免费在线观看的a站最新| 亚洲av中文无码乱人伦在线咪咕 | 男人j进入女人j内部免费网站| 亚洲精品乱码久久久久久中文字幕| 亚洲免费观看视频| 亚洲一级毛片免费在线观看| 女人被男人躁的女爽免费视频| 国产精品亚洲综合一区在线观看 | 香蕉高清免费永久在线视频| 新最免费影视大全在线播放| 久久国产亚洲观看| 在线观看免费人成视频色9 | 免费无码一区二区三区蜜桃| 亚洲色图视频在线观看| 大陆一级毛片免费视频观看| 国产特黄特色的大片观看免费视频| 亚洲国产成人久久综合碰碰动漫3d | 亚洲国产精品毛片av不卡在线| 国产又黄又爽又大的免费视频| 亚洲欧洲国产视频| 亚洲国产专区一区| 久久久久久精品免费看SSS| 特级毛片aaaa级毛片免费|