<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>评论：Netty使用初步</title>
	<atom:link href="http://www.kafka0102.com/2010/06/161.html/feed" rel="self" type="application/rss+xml" />
	<link>http://www.kafka0102.com/2010/06/161.html</link>
	<description>要有最朴素的生活与最遥远的梦想，即使明日天寒地冻、路远马亡。</description>
	<lastBuildDate>Sun, 04 Dec 2011 17:38:18 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<item>
		<title>来自：zhouyong</title>
		<link>http://www.kafka0102.com/2010/06/161.html/comment-page-1#comment-4807</link>
		<dc:creator>zhouyong</dc:creator>
		<pubDate>Sun, 04 Dec 2011 17:38:18 +0000</pubDate>
		<guid isPermaLink="false">http://www.kafka0102.com/?p=161#comment-4807</guid>
		<description>如果客户度和服务器都是走本地的127.0.0.1做测试，实时发送速率可接近10M，此时建议在Client使用16M大小的固定
channelconfig.setOption(&quot;receiveBufferSizePredictorFactory&quot;, new FixedReceiveBufferSizePredictorFactory(16776960));
否则，请在两端限速。</description>
		<content:encoded><![CDATA[<p>如果客户度和服务器都是走本地的127.0.0.1做测试，实时发送速率可接近10M，此时建议在Client使用16M大小的固定<br />
channelconfig.setOption(&#8220;receiveBufferSizePredictorFactory&#8221;, new FixedReceiveBufferSizePredictorFactory(16776960));<br />
否则，请在两端限速。</p>
]]></content:encoded>
	</item>
	<item>
		<title>来自：kafka0102</title>
		<link>http://www.kafka0102.com/2010/06/161.html/comment-page-1#comment-4806</link>
		<dc:creator>kafka0102</dc:creator>
		<pubDate>Mon, 21 Nov 2011 12:40:04 +0000</pubDate>
		<guid isPermaLink="false">http://www.kafka0102.com/?p=161#comment-4806</guid>
		<description>@ixqbar, 进程挂掉？那os自动就释放资源了。</description>
		<content:encoded><![CDATA[<p>@ixqbar, 进程挂掉？那os自动就释放资源了。</p>
]]></content:encoded>
	</item>
	<item>
		<title>来自：kafka0102</title>
		<link>http://www.kafka0102.com/2010/06/161.html/comment-page-1#comment-4805</link>
		<dc:creator>kafka0102</dc:creator>
		<pubDate>Mon, 21 Nov 2011 12:38:55 +0000</pubDate>
		<guid isPermaLink="false">http://www.kafka0102.com/?p=161#comment-4805</guid>
		<description>@ixqbar, 心跳检测分多种，如果只想检测server是否还在运行，可以发个简单的请求命令，如果涉及到运行状态的检测，就需要单独处理了。</description>
		<content:encoded><![CDATA[<p>@ixqbar, 心跳检测分多种，如果只想检测server是否还在运行，可以发个简单的请求命令，如果涉及到运行状态的检测，就需要单独处理了。</p>
]]></content:encoded>
	</item>
	<item>
		<title>来自：ixqbar</title>
		<link>http://www.kafka0102.com/2010/06/161.html/comment-page-1#comment-4804</link>
		<dc:creator>ixqbar</dc:creator>
		<pubDate>Mon, 21 Nov 2011 10:36:24 +0000</pubDate>
		<guid isPermaLink="false">http://www.kafka0102.com/?p=161#comment-4804</guid>
		<description>当MessageServer意外关闭或者中止后MessageServer中代码应该怎么做才能释放相应资源</description>
		<content:encoded><![CDATA[<p>当MessageServer意外关闭或者中止后MessageServer中代码应该怎么做才能释放相应资源</p>
]]></content:encoded>
	</item>
	<item>
		<title>来自：ixqbar</title>
		<link>http://www.kafka0102.com/2010/06/161.html/comment-page-1#comment-4803</link>
		<dc:creator>ixqbar</dc:creator>
		<pubDate>Fri, 18 Nov 2011 16:54:23 +0000</pubDate>
		<guid isPermaLink="false">http://www.kafka0102.com/?p=161#comment-4803</guid>
		<description>服务端如何实现心跳检测功能呢？客户端又如何做发送心跳？刚接触，小白了</description>
		<content:encoded><![CDATA[<p>服务端如何实现心跳检测功能呢？客户端又如何做发送心跳？刚接触，小白了</p>
]]></content:encoded>
	</item>
	<item>
		<title>来自：jimmee</title>
		<link>http://www.kafka0102.com/2010/06/161.html/comment-page-1#comment-4418</link>
		<dc:creator>jimmee</dc:creator>
		<pubDate>Sat, 02 Jul 2011 22:09:35 +0000</pubDate>
		<guid isPermaLink="false">http://www.kafka0102.com/?p=161#comment-4418</guid>
		<description>看了楼主关于netty的两篇博文，lz写得很好。

只是针对MessageClient你说的问题，我觉得用不着跨过netty来实现啊。 其实连接一但建立，对客户端和服务器端得处理来说，没有什么区别啊。

“但是，我想要的是一个连接池，并且如何写数据也不应该在channelConnected中，这样对于动态的数据，只能在构造函数中传递需要写的数据了。”

你说的连接池是connection的连接池吧？这个你只需要将建立成功的channel放到一个池里即可啊。

写数据是不一定在channelConnected中啊，只不过对于客户端而言，一般都是协议请求的发起者，所以一旦建立好就发送数据，但是这个不是强制的，完全可以根据自己协议来处理的。</description>
		<content:encoded><![CDATA[<p>看了楼主关于netty的两篇博文，lz写得很好。</p>
<p>只是针对MessageClient你说的问题，我觉得用不着跨过netty来实现啊。 其实连接一但建立，对客户端和服务器端得处理来说，没有什么区别啊。</p>
<p>“但是，我想要的是一个连接池，并且如何写数据也不应该在channelConnected中，这样对于动态的数据，只能在构造函数中传递需要写的数据了。”</p>
<p>你说的连接池是connection的连接池吧？这个你只需要将建立成功的channel放到一个池里即可啊。</p>
<p>写数据是不一定在channelConnected中啊，只不过对于客户端而言，一般都是协议请求的发起者，所以一旦建立好就发送数据，但是这个不是强制的，完全可以根据自己协议来处理的。</p>
]]></content:encoded>
	</item>
	<item>
		<title>来自：kafka0102</title>
		<link>http://www.kafka0102.com/2010/06/161.html/comment-page-1#comment-4408</link>
		<dc:creator>kafka0102</dc:creator>
		<pubDate>Tue, 21 Jun 2011 03:00:27 +0000</pubDate>
		<guid isPermaLink="false">http://www.kafka0102.com/?p=161#comment-4408</guid>
		<description>2、netty的那个图已经算是比较清晰了。netty的buffer维护了两个位置信息，writerIndex表示从客户端读到的数据写入buffer的最高位置，readerIndex表示程序读buffer数据的最新位置。比如客户端要传入100字节数据，一开始readerIndex和writerIndex为0，netty首先读了100长度的数据进来，这时writerIndex为100，实际可用的buffer数据就在（writerIndex-readerIndex）之间，接着程序端做实际的逻辑处理就要不断读buffer，那么readerIndex就不断增长，但可用的buffer会一直是（writerIndex-readerIndex）之间，知道无可用的数据为止。
3、以一个例子来说，假如客户端要发送信息&quot;hello&quot;,那么实际的数据包是：前4个字节是5，表示后面的实际数据长度，紧接着是5个字节的&quot;hello&quot;，我说的就是这个意思。</description>
		<content:encoded><![CDATA[<p>2、netty的那个图已经算是比较清晰了。netty的buffer维护了两个位置信息，writerIndex表示从客户端读到的数据写入buffer的最高位置，readerIndex表示程序读buffer数据的最新位置。比如客户端要传入100字节数据，一开始readerIndex和writerIndex为0，netty首先读了100长度的数据进来，这时writerIndex为100，实际可用的buffer数据就在（writerIndex-readerIndex）之间，接着程序端做实际的逻辑处理就要不断读buffer，那么readerIndex就不断增长，但可用的buffer会一直是（writerIndex-readerIndex）之间，知道无可用的数据为止。<br />
3、以一个例子来说，假如客户端要发送信息&#8221;hello&#8221;,那么实际的数据包是：前4个字节是5，表示后面的实际数据长度，紧接着是5个字节的&#8221;hello&#8221;，我说的就是这个意思。</p>
]]></content:encoded>
	</item>
	<item>
		<title>来自：网络时空</title>
		<link>http://www.kafka0102.com/2010/06/161.html/comment-page-1#comment-4405</link>
		<dc:creator>网络时空</dc:creator>
		<pubDate>Mon, 20 Jun 2011 10:47:48 +0000</pubDate>
		<guid isPermaLink="false">http://www.kafka0102.com/?p=161#comment-4405</guid>
		<description>netty的api中描述如下
Sequential Access Indexing

ChannelBuffer provides two pointer variables to support sequential read and write operations - readerIndex for a read operation and writerIndex for a write operation respectively. The following diagram shows how a buffer is segmented into three areas by the two pointers:
      +-------------------+------------------+------------------+
      &#124; discardable bytes &#124;  readable bytes  &#124;  writable bytes  &#124;
      &#124;                   &#124;     (CONTENT)    &#124;                  &#124;
      +-------------------+------------------+------------------+
      &#124;                   &#124;                  &#124;                  &#124;
      0      &lt;=      readerIndex   &lt;=   writerIndex    &lt;=    capacity


readableBytes

int readableBytes()
Returns the number of readable bytes which is equal to (this.writerIndex - this.readerIndex).
writableBytes

int writableBytes()
Returns the number of writable bytes which is equal to (this.capacity - this.writerIndex).</description>
		<content:encoded><![CDATA[<p>netty的api中描述如下<br />
Sequential Access Indexing</p>
<p>ChannelBuffer provides two pointer variables to support sequential read and write operations &#8211; readerIndex for a read operation and writerIndex for a write operation respectively. The following diagram shows how a buffer is segmented into three areas by the two pointers:<br />
      +&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;+<br />
      | discardable bytes |  readable bytes  |  writable bytes  |<br />
      |                   |     (CONTENT)    |                  |<br />
      +&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;+<br />
      |                   |                  |                  |<br />
      0      &lt;=      readerIndex   &lt;=   writerIndex    &lt;=    capacity</p>
<p>readableBytes</p>
<p>int readableBytes()<br />
Returns the number of readable bytes which is equal to (this.writerIndex &#8211; this.readerIndex).<br />
writableBytes</p>
<p>int writableBytes()<br />
Returns the number of writable bytes which is equal to (this.capacity &#8211; this.writerIndex).</p>
]]></content:encoded>
	</item>
	<item>
		<title>来自：网络时空</title>
		<link>http://www.kafka0102.com/2010/06/161.html/comment-page-1#comment-4404</link>
		<dc:creator>网络时空</dc:creator>
		<pubDate>Mon, 20 Jun 2011 10:43:38 +0000</pubDate>
		<guid isPermaLink="false">http://www.kafka0102.com/?p=161#comment-4404</guid>
		<description>非常感谢兄弟的及时来信！
1。兄弟提到的writerIndex是netty的api上提到的啊

2.根据netty的上述图中api中所示
readableBytes= this.writerIndex - this.readerIndex
所以，我们必须知道，此时writerIndex和readerIndex的pointer位置啊
根据netty api的描述，每次读的时候指针readerIndex是会移动变化的啊

3.楼上上面提到了头4个字节表示“真正的内容长度”, buffer.getInt(buffer.readerIndex())表示&quot;实际的内容长度&quot;,这两个概念如何具体理解？有些迷惑！
        int dataLength = buffer.getInt(buffer.readerIndex());
        if (buffer.readableBytes() &lt; dataLength + 4) {
            return null;//(2)
        }</description>
		<content:encoded><![CDATA[<p>非常感谢兄弟的及时来信！<br />
1。兄弟提到的writerIndex是netty的api上提到的啊</p>
<p>2.根据netty的上述图中api中所示<br />
readableBytes= this.writerIndex &#8211; this.readerIndex<br />
所以，我们必须知道，此时writerIndex和readerIndex的pointer位置啊<br />
根据netty api的描述，每次读的时候指针readerIndex是会移动变化的啊</p>
<p>3.楼上上面提到了头4个字节表示“真正的内容长度”, buffer.getInt(buffer.readerIndex())表示&#8221;实际的内容长度&#8221;,这两个概念如何具体理解？有些迷惑！<br />
        int dataLength = buffer.getInt(buffer.readerIndex());<br />
        if (buffer.readableBytes() &lt; dataLength + 4) {<br />
            return null;//(2)<br />
        }</p>
]]></content:encoded>
	</item>
	<item>
		<title>来自：kafka0102</title>
		<link>http://www.kafka0102.com/2010/06/161.html/comment-page-1#comment-4403</link>
		<dc:creator>kafka0102</dc:creator>
		<pubDate>Mon, 20 Jun 2011 09:42:35 +0000</pubDate>
		<guid isPermaLink="false">http://www.kafka0102.com/?p=161#comment-4403</guid>
		<description>好久的文章了，手边没有netty的文档和源码，简单的回复一下，具体的你可以参考他的文档。
1、传来的数据包格式应该是头四个字节（int型）表示真正的内容的长度，所以先要判断 if (buffer.readableBytes() &lt; 4) 不满足条件就返回。
2、buffer.readableBytes() &lt; dataLength + 4 这里加4就是整个数据包长度，而实际的内容长度是dataLength。
3、接下来就越过表示长度的头四个字节：skipBytes
4、最后就是读内容了。
至于你这writerIndex，我没从这篇文章grep到，还是自行理解吧。</description>
		<content:encoded><![CDATA[<p>好久的文章了，手边没有netty的文档和源码，简单的回复一下，具体的你可以参考他的文档。<br />
1、传来的数据包格式应该是头四个字节（int型）表示真正的内容的长度，所以先要判断 if (buffer.readableBytes() < 4) 不满足条件就返回。<br />
2、buffer.readableBytes() < dataLength + 4 这里加4就是整个数据包长度，而实际的内容长度是dataLength。<br />
3、接下来就越过表示长度的头四个字节：skipBytes<br />
4、最后就是读内容了。<br />
至于你这writerIndex，我没从这篇文章grep到，还是自行理解吧。</p>
]]></content:encoded>
	</item>
	<item>
		<title>来自：网络时空</title>
		<link>http://www.kafka0102.com/2010/06/161.html/comment-page-1#comment-4401</link>
		<dc:creator>网络时空</dc:creator>
		<pubDate>Mon, 20 Jun 2011 08:36:05 +0000</pubDate>
		<guid isPermaLink="false">http://www.kafka0102.com/?p=161#comment-4401</guid>
		<description>public class MessageDecoder extends FrameDecoder {
 
    @Override
    protected Object decode(
            ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) throws Exception {
        if (buffer.readableBytes() &lt; 4) {
            return null;//(1)
        }
        int dataLength = buffer.getInt(buffer.readerIndex());
        if (buffer.readableBytes() &lt; dataLength + 4) {
            return null;//(2)
        }
 
        buffer.skipBytes(4);//(3)
        byte[] decoded = new byte[dataLength];
        buffer.readBytes(decoded);
        String msg = new String(decoded);//(4)
        return msg;
    }
}

这段代码的readerIndex ,writerIndex的指针如何变化，十分迷惑，不知道兄弟能否具体说明一下，谢了</description>
		<content:encoded><![CDATA[<p>public class MessageDecoder extends FrameDecoder {</p>
<p>    @Override<br />
    protected Object decode(<br />
            ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) throws Exception {<br />
        if (buffer.readableBytes() &lt; 4) {<br />
            return null;//(1)<br />
        }<br />
        int dataLength = buffer.getInt(buffer.readerIndex());<br />
        if (buffer.readableBytes() &lt; dataLength + 4) {<br />
            return null;//(2)<br />
        }</p>
<p>        buffer.skipBytes(4);//(3)<br />
        byte[] decoded = new byte[dataLength];<br />
        buffer.readBytes(decoded);<br />
        String msg = new String(decoded);//(4)<br />
        return msg;<br />
    }<br />
}</p>
<p>这段代码的readerIndex ,writerIndex的指针如何变化，十分迷惑，不知道兄弟能否具体说明一下，谢了</p>
]]></content:encoded>
	</item>
	<item>
		<title>来自：kafka0102</title>
		<link>http://www.kafka0102.com/2010/06/161.html/comment-page-1#comment-2216</link>
		<dc:creator>kafka0102</dc:creator>
		<pubDate>Sun, 28 Nov 2010 10:27:37 +0000</pubDate>
		<guid isPermaLink="false">http://www.kafka0102.com/?p=161#comment-2216</guid>
		<description>@leeing, 
不客气。共同进步。</description>
		<content:encoded><![CDATA[<p>@leeing,<br />
不客气。共同进步。</p>
]]></content:encoded>
	</item>
	<item>
		<title>来自：leeing</title>
		<link>http://www.kafka0102.com/2010/06/161.html/comment-page-1#comment-2215</link>
		<dc:creator>leeing</dc:creator>
		<pubDate>Sun, 28 Nov 2010 07:50:53 +0000</pubDate>
		<guid isPermaLink="false">http://www.kafka0102.com/?p=161#comment-2215</guid>
		<description>非常感谢！我按照您的提示检查了一下，正是因为这个问题。

经检测，MTU 在我的机器上最多是 1492 个字节，在 windows xp 中，cmd中运行：

&gt; ping -l 1492 -f localhost

是可以正确ping成功的。

如果用：

&gt; ping -l 1493 -f localhost

则会回应说：
Packet needs to be fragmented but DF set.</description>
		<content:encoded><![CDATA[<p>非常感谢！我按照您的提示检查了一下，正是因为这个问题。</p>
<p>经检测，MTU 在我的机器上最多是 1492 个字节，在 windows xp 中，cmd中运行：</p>
<p>&gt; ping -l 1492 -f localhost</p>
<p>是可以正确ping成功的。</p>
<p>如果用：</p>
<p>&gt; ping -l 1493 -f localhost</p>
<p>则会回应说：<br />
Packet needs to be fragmented but DF set.</p>
]]></content:encoded>
	</item>
	<item>
		<title>来自：kafka0102</title>
		<link>http://www.kafka0102.com/2010/06/161.html/comment-page-1#comment-2213</link>
		<dc:creator>kafka0102</dc:creator>
		<pubDate>Sun, 28 Nov 2010 02:48:01 +0000</pubDate>
		<guid isPermaLink="false">http://www.kafka0102.com/?p=161#comment-2213</guid>
		<description>@leeing, 
看你的描述，现象是服务端接受大数据会有丢包的情况。你可以检查下网络情况是否正常，丢包的常见情况是网络连接差造成。另一方面，这1500个字节大小是默认的MTU，你可以检查两端机器的MTU大小是否都是1500,尤其是服务端，如果MTU大时，可能会丢包。对于客户端，可以设置tcp nodelay，确保数据都传输过去。</description>
		<content:encoded><![CDATA[<p>@leeing,<br />
看你的描述，现象是服务端接受大数据会有丢包的情况。你可以检查下网络情况是否正常，丢包的常见情况是网络连接差造成。另一方面，这1500个字节大小是默认的MTU，你可以检查两端机器的MTU大小是否都是1500,尤其是服务端，如果MTU大时，可能会丢包。对于客户端，可以设置tcp nodelay，确保数据都传输过去。</p>
]]></content:encoded>
	</item>
	<item>
		<title>来自：leeing</title>
		<link>http://www.kafka0102.com/2010/06/161.html/comment-page-1#comment-2211</link>
		<dc:creator>leeing</dc:creator>
		<pubDate>Sat, 27 Nov 2010 12:34:30 +0000</pubDate>
		<guid isPermaLink="false">http://www.kafka0102.com/?p=161#comment-2211</guid>
		<description>所以，我的问题是：这样的情况是否是正常的？即发送方write成功，但接收方无法收到对方发送的完整数据，就算发生这样情况的概率比较小。

如果是这样，那么，根据您前面说的，只能在超时后要求重传吗？
如果不是，那么，应该采取什么样的策略来避免这样的情况发生呢？

启动时，我使用的是：ServerBootstrap，Netty 版本是：3.2.2</description>
		<content:encoded><![CDATA[<p>所以，我的问题是：这样的情况是否是正常的？即发送方write成功，但接收方无法收到对方发送的完整数据，就算发生这样情况的概率比较小。</p>
<p>如果是这样，那么，根据您前面说的，只能在超时后要求重传吗？<br />
如果不是，那么，应该采取什么样的策略来避免这样的情况发生呢？</p>
<p>启动时，我使用的是：ServerBootstrap，Netty 版本是：3.2.2</p>
]]></content:encoded>
	</item>
	<item>
		<title>来自：leeing</title>
		<link>http://www.kafka0102.com/2010/06/161.html/comment-page-1#comment-2210</link>
		<dc:creator>leeing</dc:creator>
		<pubDate>Sat, 27 Nov 2010 12:20:36 +0000</pubDate>
		<guid isPermaLink="false">http://www.kafka0102.com/?p=161#comment-2210</guid>
		<description>谢谢您的回复。实际上，我正是不断用while循环来操作的：

发送方：channel.write(message) , message 长度是4096，在这里，我想实现的是文件分块传输的功能，这里的message是指某个文件的一部份，其大小是4096字节。

然后在接收端，我要将这段文件重新组装成一个文件：

while (buf.readableBytes() &lt; 4096) {
     buf = (ChannelBuffer) e.getMessage();
     // log.debug(&quot;buffer size:&quot;+buf.capacity());
}

问题就在于，发送方已经成功地 write，但是接收方运行到这一段语句的时候，如果去掉注释，会发现一个情况，就是buf的大小有可能始终在1500个字节，然后就陷入死循环无法继续读取下去,不断地会打印：buffer size : 1500。
--------

如果发送端和接收端的都在同一台机器上，若message的比较小，比如128个字节的话，是不会出现死循环的情况的；然而，默认情况下，如果message到了1024个字节就已经会陷入死循环。

如果，单机测试时加一段这样的配置代码：

channelconfig.setOption(&quot;receiveBufferSizePredictorFactory&quot;, new FixedReceiveBufferSizePredictorFactory(8192));

那么单机上就可以实现4096个字节的传输，但注意，5000字节又可能会出现死循环。（所以我也不清楚这句话中的8192究竟起到什么作用）。

不过，最麻烦的地方是，如果发送端和接收端在不同的机器上，即使加了上面的配置代码，也仍然无效，无法传输4096个字节，经常在1500个字节左右就停止了，再也没能新的数据过来。

不知道描述得是否清楚，总之，就是发送方write成功，但接收方可能收不到对方write的所有字节（如果坚持读取，可能陷入死循环），似乎有时会出现数据缺失的现象。单机上配置一下参数，可以暂时地不会出现这个问题，但切换到多机情况下，又不行了。</description>
		<content:encoded><![CDATA[<p>谢谢您的回复。实际上，我正是不断用while循环来操作的：</p>
<p>发送方：channel.write(message) , message 长度是4096，在这里，我想实现的是文件分块传输的功能，这里的message是指某个文件的一部份，其大小是4096字节。</p>
<p>然后在接收端，我要将这段文件重新组装成一个文件：</p>
<p>while (buf.readableBytes() &lt; 4096) {<br />
     buf = (ChannelBuffer) e.getMessage();<br />
     // log.debug(&quot;buffer size:&quot;+buf.capacity());<br />
}</p>
<p>问题就在于，发送方已经成功地 write，但是接收方运行到这一段语句的时候，如果去掉注释，会发现一个情况，就是buf的大小有可能始终在1500个字节，然后就陷入死循环无法继续读取下去,不断地会打印：buffer size : 1500。<br />
&#8212;&#8212;&#8211;</p>
<p>如果发送端和接收端的都在同一台机器上，若message的比较小，比如128个字节的话，是不会出现死循环的情况的；然而，默认情况下，如果message到了1024个字节就已经会陷入死循环。</p>
<p>如果，单机测试时加一段这样的配置代码：</p>
<p>channelconfig.setOption(&quot;receiveBufferSizePredictorFactory&quot;, new FixedReceiveBufferSizePredictorFactory(8192));</p>
<p>那么单机上就可以实现4096个字节的传输，但注意，5000字节又可能会出现死循环。（所以我也不清楚这句话中的8192究竟起到什么作用）。</p>
<p>不过，最麻烦的地方是，如果发送端和接收端在不同的机器上，即使加了上面的配置代码，也仍然无效，无法传输4096个字节，经常在1500个字节左右就停止了，再也没能新的数据过来。</p>
<p>不知道描述得是否清楚，总之，就是发送方write成功，但接收方可能收不到对方write的所有字节（如果坚持读取，可能陷入死循环），似乎有时会出现数据缺失的现象。单机上配置一下参数，可以暂时地不会出现这个问题，但切换到多机情况下，又不行了。</p>
]]></content:encoded>
	</item>
	<item>
		<title>来自：kafka0102</title>
		<link>http://www.kafka0102.com/2010/06/161.html/comment-page-1#comment-2209</link>
		<dc:creator>kafka0102</dc:creator>
		<pubDate>Sat, 27 Nov 2010 10:38:53 +0000</pubDate>
		<guid isPermaLink="false">http://www.kafka0102.com/?p=161#comment-2209</guid>
		<description>@leeing, 
就你的问题来说，是服务端读的方式不对。如果是自己操作channel buffer读数据，读数据显然不能读一次，而是在一个超时范围内不断的while循环，直到读到完整的数据或者超时关闭连接。如果使用netty，netty的几个decoder已经做了这样的数据，而你只要取回数据就行。</description>
		<content:encoded><![CDATA[<p>@leeing,<br />
就你的问题来说，是服务端读的方式不对。如果是自己操作channel buffer读数据，读数据显然不能读一次，而是在一个超时范围内不断的while循环，直到读到完整的数据或者超时关闭连接。如果使用netty，netty的几个decoder已经做了这样的数据，而你只要取回数据就行。</p>
]]></content:encoded>
	</item>
	<item>
		<title>来自：leeing</title>
		<link>http://www.kafka0102.com/2010/06/161.html/comment-page-1#comment-2208</link>
		<dc:creator>leeing</dc:creator>
		<pubDate>Sat, 27 Nov 2010 04:55:54 +0000</pubDate>
		<guid isPermaLink="false">http://www.kafka0102.com/?p=161#comment-2208</guid>
		<description>您好，我现在遇到一个问题：

在发送方 channel.write(message) 成功，不过这里message比较大，比如是4096个字节。

在接收方如果使用：

 if (buffer.readableBytes() &lt; 4096) {
            return null;//(1)
 }

有时会发生这样的情况，即 buffer.readableBytes 一直都无法读够4096，比如只能读到 1500 个字节，那么这样的话，本次接受到的消息将无法被解析，返回null。

而我的需求是每次必须读到4096字节才往下运行，有什么方法可以做到吗？

比如设置参数？或者什么其它的变通的方法？或者说这种情况是不可避免的，即 write 成功，接收端receive到的字节数总有可能小于 write 的字节数？

thanks!</description>
		<content:encoded><![CDATA[<p>您好，我现在遇到一个问题：</p>
<p>在发送方 channel.write(message) 成功，不过这里message比较大，比如是4096个字节。</p>
<p>在接收方如果使用：</p>
<p> if (buffer.readableBytes() &lt; 4096) {<br />
            return null;//(1)<br />
 }</p>
<p>有时会发生这样的情况，即 buffer.readableBytes 一直都无法读够4096，比如只能读到 1500 个字节，那么这样的话，本次接受到的消息将无法被解析，返回null。</p>
<p>而我的需求是每次必须读到4096字节才往下运行，有什么方法可以做到吗？</p>
<p>比如设置参数？或者什么其它的变通的方法？或者说这种情况是不可避免的，即 write 成功，接收端receive到的字节数总有可能小于 write 的字节数？</p>
<p>thanks!</p>
]]></content:encoded>
	</item>
	<item>
		<title>来自：kafka0102</title>
		<link>http://www.kafka0102.com/2010/06/161.html/comment-page-1#comment-1251</link>
		<dc:creator>kafka0102</dc:creator>
		<pubDate>Thu, 18 Nov 2010 03:28:09 +0000</pubDate>
		<guid isPermaLink="false">http://www.kafka0102.com/?p=161#comment-1251</guid>
		<description>@jombowang, 
你说的操作Channel是可以的，但它还是太底层了，应该有个更好的封装。当然，netty毕竟是个服务端框架，它没有做客户端连接池的封装也很正常。</description>
		<content:encoded><![CDATA[<p>@jombowang,<br />
你说的操作Channel是可以的，但它还是太底层了，应该有个更好的封装。当然，netty毕竟是个服务端框架，它没有做客户端连接池的封装也很正常。</p>
]]></content:encoded>
	</item>
	<item>
		<title>来自：jombowang</title>
		<link>http://www.kafka0102.com/2010/06/161.html/comment-page-1#comment-1188</link>
		<dc:creator>jombowang</dc:creator>
		<pubDate>Wed, 17 Nov 2010 16:55:39 +0000</pubDate>
		<guid isPermaLink="false">http://www.kafka0102.com/?p=161#comment-1188</guid>
		<description>关于你说的“并且如何写数据也不应该在channelConnected中，这样对于动态的数据，只能在构造函数中传递需要写的数据了”，其实例子只是展现了一种客户端向服务器发送数据的方式，可能这么写省事吧。其实你的客户端是可以这样写的：
 
ChannelFuture future = bootstrap.connect(new InetSocketAddress(host,  port));
Channel channel = future.awaitUninterruptibly().getChannel();
 if (future.isSuccess()) {
            channel.write(&quot;哈哈，发一次&quot;)
   }

下面就是失败的处理以及释放资源</description>
		<content:encoded><![CDATA[<p>关于你说的“并且如何写数据也不应该在channelConnected中，这样对于动态的数据，只能在构造函数中传递需要写的数据了”，其实例子只是展现了一种客户端向服务器发送数据的方式，可能这么写省事吧。其实你的客户端是可以这样写的：</p>
<p>ChannelFuture future = bootstrap.connect(new InetSocketAddress(host,  port));<br />
Channel channel = future.awaitUninterruptibly().getChannel();<br />
 if (future.isSuccess()) {<br />
            channel.write(&#8220;哈哈，发一次&#8221;)<br />
   }</p>
<p>下面就是失败的处理以及释放资源</p>
]]></content:encoded>
	</item>
	<item>
		<title>来自：JAVA&#39;s NIO, Netty And Mina.</title>
		<link>http://www.kafka0102.com/2010/06/161.html/comment-page-1#comment-125</link>
		<dc:creator>JAVA&#39;s NIO, Netty And Mina.</dc:creator>
		<pubDate>Fri, 01 Oct 2010 16:21:45 +0000</pubDate>
		<guid isPermaLink="false">http://www.kafka0102.com/?p=161#comment-125</guid>
		<description>[...] Netty使用初步 [...]</description>
		<content:encoded><![CDATA[<p>[...] Netty使用初步 [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>来自：kafka0102</title>
		<link>http://www.kafka0102.com/2010/06/161.html/comment-page-1#comment-55</link>
		<dc:creator>kafka0102</dc:creator>
		<pubDate>Tue, 13 Jul 2010 09:39:18 +0000</pubDate>
		<guid isPermaLink="false">http://www.kafka0102.com/?p=161#comment-55</guid>
		<description>netty来保持长连接是没有问题的。你说的掉线是在在哪一层次呢？是客户端到web server还是web server到netty？对于聊天室的实现，你使用的是哪种服务器推（拉）方式？这种session的中断可能实现上的偏差造成，可以跟踪连接断开的异常排查。像netty程序，继承SimpleChannelUpstreamHandler的handler有channelDisconnected、channelClosed、exceptionCaught，可以检查是否有这3种异常的事件出现。</description>
		<content:encoded><![CDATA[<p>netty来保持长连接是没有问题的。你说的掉线是在在哪一层次呢？是客户端到web server还是web server到netty？对于聊天室的实现，你使用的是哪种服务器推（拉）方式？这种session的中断可能实现上的偏差造成，可以跟踪连接断开的异常排查。像netty程序，继承SimpleChannelUpstreamHandler的handler有channelDisconnected、channelClosed、exceptionCaught，可以检查是否有这3种异常的事件出现。</p>
]]></content:encoded>
	</item>
	<item>
		<title>来自：tony zhang</title>
		<link>http://www.kafka0102.com/2010/06/161.html/comment-page-1#comment-54</link>
		<dc:creator>tony zhang</dc:creator>
		<pubDate>Tue, 13 Jul 2010 08:17:13 +0000</pubDate>
		<guid isPermaLink="false">http://www.kafka0102.com/?p=161#comment-54</guid>
		<description>我如果用他来开发的一个web和后天聊天系统怎么样？
有什么注意的问题，我们的一期项目，经常会出现掉线的问题，不知道如何解决！
大虾！</description>
		<content:encoded><![CDATA[<p>我如果用他来开发的一个web和后天聊天系统怎么样？<br />
有什么注意的问题，我们的一期项目，经常会出现掉线的问题，不知道如何解决！<br />
大虾！</p>
]]></content:encoded>
	</item>
	<item>
		<title>来自：tony zhang</title>
		<link>http://www.kafka0102.com/2010/06/161.html/comment-page-1#comment-53</link>
		<dc:creator>tony zhang</dc:creator>
		<pubDate>Tue, 13 Jul 2010 08:15:34 +0000</pubDate>
		<guid isPermaLink="false">http://www.kafka0102.com/?p=161#comment-53</guid>
		<description>博客写的非常不错，O(∩_∩)O谢谢，飘过！~~~~~~~~</description>
		<content:encoded><![CDATA[<p>博客写的非常不错，O(∩_∩)O谢谢，飘过！~~~~~~~~</p>
]]></content:encoded>
	</item>
	<item>
		<title>来自：Netty实现原理浅析 &#124; Jim的blog</title>
		<link>http://www.kafka0102.com/2010/06/161.html/comment-page-1#comment-21</link>
		<dc:creator>Netty实现原理浅析 &#124; Jim的blog</dc:creator>
		<pubDate>Fri, 25 Jun 2010 07:49:46 +0000</pubDate>
		<guid isPermaLink="false">http://www.kafka0102.com/?p=161#comment-21</guid>
		<description>[...] Netty是JBoss出品的高效的Java NIO开发框架，关于其使用，可参考我的另一篇文章 netty使用初步。本文将主要分析Netty实现方面的东西，由于精力有限，本人并没有对其源码做了极细致的研 究。如果下面的内容有错误或不严谨的地方，也请指正和谅解。对于Netty使用者来说，Netty提供了几个典型的example，并有详尽的API doc和guide doc，本文的一些内容及图示也来自于Netty的文档，特此致谢。 [...]</description>
		<content:encoded><![CDATA[<p>[...] Netty是JBoss出品的高效的Java NIO开发框架，关于其使用，可参考我的另一篇文章 netty使用初步。本文将主要分析Netty实现方面的东西，由于精力有限，本人并没有对其源码做了极细致的研 究。如果下面的内容有错误或不严谨的地方，也请指正和谅解。对于Netty使用者来说，Netty提供了几个典型的example，并有详尽的API doc和guide doc，本文的一些内容及图示也来自于Netty的文档，特此致谢。 [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>来自：kafka0102的边城客栈 &#187; Blog Archive &#187; Netty实现原理浅析</title>
		<link>http://www.kafka0102.com/2010/06/161.html/comment-page-1#comment-18</link>
		<dc:creator>kafka0102的边城客栈 &#187; Blog Archive &#187; Netty实现原理浅析</dc:creator>
		<pubDate>Sat, 19 Jun 2010 20:21:24 +0000</pubDate>
		<guid isPermaLink="false">http://www.kafka0102.com/?p=161#comment-18</guid>
		<description>[...] Netty是JBoss出品的高效的Java NIO开发框架，关于其使用，可参考我的另一篇文章 netty使用初步。本文将主要分析Netty实现方面的东西，由于精力有限，本人并没有对其源码做了极细致的研 究。如果下面的内容有错误或不严谨的地方，也请指正和谅解。对于Netty使用者来说，Netty提供了几个典型的example，并有详尽的API doc和guide doc，本文的一些内容及图示也来自于Netty的文档，特此致谢。 [...]</description>
		<content:encoded><![CDATA[<p>[...] Netty是JBoss出品的高效的Java NIO开发框架，关于其使用，可参考我的另一篇文章 netty使用初步。本文将主要分析Netty实现方面的东西，由于精力有限，本人并没有对其源码做了极细致的研 究。如果下面的内容有错误或不严谨的地方，也请指正和谅解。对于Netty使用者来说，Netty提供了几个典型的example，并有详尽的API doc和guide doc，本文的一些内容及图示也来自于Netty的文档，特此致谢。 [...]</p>
]]></content:encoded>
	</item>
</channel>
</rss>

