<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
    主站蜘蛛池模板: 四虎影视永久免费观看网址| 黄色免费网站网址| 免费一看一级毛片| 亚洲av永久无码精品秋霞电影秋 | 亚洲国产精品综合福利专区| 最近免费中文字幕MV在线视频3| 亚洲区小说区图片区| 一区二区三区免费视频网站 | 91精品免费高清在线| 亚洲美女aⅴ久久久91| 亚洲免费福利在线视频| 亚洲一区免费视频| 日本久久久免费高清| 真正全免费视频a毛片| 亚洲精品国产日韩无码AV永久免费网| 免费国产va在线观看| 国产亚洲精AA在线观看SEE| 国内精品一级毛片免费看| 亚洲黄色免费在线观看| 免费人成在线视频| 外国成人网在线观看免费视频| 久久久久亚洲Av片无码v| 18禁美女裸体免费网站| 国产亚洲日韩在线三区| 无码日韩精品一区二区三区免费| 亚洲影视一区二区| 国产免费小视频在线观看| 一级毛片免费不卡| 亚洲av色福利天堂| 国产一精品一AV一免费孕妇| 黄页免费视频播放在线播放| 亚洲国产精品VA在线看黑人| 国产人在线成免费视频| 免费精品国自产拍在线播放| 亚洲情综合五月天| 中国在线观看免费国语版| www永久免费视频| 亚洲国产成人久久综合一区| 免费大香伊蕉在人线国产| 无码免费一区二区三区免费播放| 亚洲午夜理论片在线观看|