我就是在最簡單的Netty服務器客戶端上修改,使其能發送1MB以上的資料,資料源是XML檔案,客戶端一般得到10KB大小的檔案
服務器端:
public class Server {
public void bind(int port) throws Exception{
EventLoopGroup bossGroup=new NioEventLoopGroup();
EventLoopGroup workerGroup=new NioEventLoopGroup();
try {
ServerBootstrap serverBootstrap=new ServerBootstrap();
serverBootstrap.group(bossGroup,workerGroup)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 10)
.childHandler(new ChildChannelHander());
//系結埠
ChannelFuture future=serverBootstrap.bind(port).sync();
//等待服務端監聽埠關閉
future.channel().closeFuture().sync();
} finally{
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
private class ChildChannelHander extends ChannelInitializer<SocketChannel>{
@Override
protected void initChannel(SocketChannel arg0) {
try {
arg0.pipeline().addLast(new StringEncoder(CharsetUtil.UTF_8));
arg0.pipeline().addLast(new FixedLengthFrameDecoder(10));
arg0.pipeline().addLast(new StringDecoder(CharsetUtil.UTF_8));
arg0.pipeline().addLast(new ServerHandler());
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws Exception {
int port=5678;
System.out.println("Server: Status-> Running.");
new Server().bind(port);
}
}
服務類:
public class ServerHandler extends ChannelHandlerAdapter{
private File file;
private byte [] bytes;
private FileInputStream fileInputStream;
private BufferedInputStream bufferedInputStream;
private static boolean DEBUG=true;
public ServerHandler() throws IOException{
file=new File("D://1MB.txt");
bytes=new byte[2047];
fileInputStream=new FileInputStream(file);
bufferedInputStream=new BufferedInputStream(fileInputStream);
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object object){
try {
String clientRequest=(String)object;
if(DEBUG)
System.out.println("Server:request->"+clientRequest);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx){
if(DEBUG)
System.out.println("Server:Send data.");
try {
Send(ctx);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause){
ctx.close();
}
private void Send(ChannelHandlerContext ctx) throws IOException{
int counter=0;
while ((counter=bufferedInputStream.read(bytes))!=-1){
String string=new String(bytes, 0, counter);
ctx.writeAndFlush(string);
}
}
}
客戶端:
public class Client {
public void connect (int port, String host) throws Exception{
EventLoopGroup group=new NioEventLoopGroup();
try {
Bootstrap bootstrap=new Bootstrap();
bootstrap.group(group).channel(NioSocketChannel.class)
.option(ChannelOption.TCP_NODELAY, true)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception{
ch.pipeline().addLast(new StringEncoder(CharsetUtil.UTF_8));
ch.pipeline().addLast(new FixedLengthFrameDecoder(1024));
ch.pipeline().addLast(new ClientHandler());
}
});
ChannelFuture future=bootstrap.connect(host,port).sync();
future.channel().closeFuture().sync();
} finally {
group.shutdownGracefully();
}
}
public static void main(String[] args) throws Exception {
int port=5678;
System.out.println("Client: Status-> Running.");
new Client().connect(port, "127.0.0.1");
}
}
服務類:
public class ClientHandler extends ChannelHandlerAdapter {
private static final Logger logger = Logger.getLogger(ClientHandler.class.getName());
private byte[] msg;
private static boolean DEBUG = true;
private FileOutputStream fileOutputStream;
private File file;
public ClientHandler() throws IOException {
file = new File("D://RECV.xml");
fileOutputStream = new FileOutputStream(file);
}
@Override
public void channelActive(ChannelHandlerContext ctx) {
msg = ("COMMANDSTR").getBytes();
ByteBuf buf = Unpooled.buffer(msg.length);
buf.writeBytes(msg);
ctx.writeAndFlush(buf);
// 發送SEND命令
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object object) throws Exception {
ByteBuf message = (ByteBuf) object;
byte[] bytes = new byte[message.readableBytes()];
message.readBytes(bytes);
fileOutputStream.write(bytes);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
logger.warning("Exception:" + cause.getMessage());
ctx.close();
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
fileOutputStream.close();
ctx.close();
if (DEBUG)
System.out.println("Client:Recv over.");
}
}
代碼雖然不多,我嘗試過自定義的解碼器,固定長的解碼器,結果都是一樣的;當我更換資料源為txt檔案時,結果仍舊還是一樣的,我曾經嘗試抓包查看,發現服務器發送10多KB后就停止發送資料了,我實在是不能理解這到底是為什么?請大神幫我解答問題!
uj5u.com熱心網友回復:
我仔細查找服務器端存在的例外,果不其然發現了一條:Server: Exception->你的主機中的軟體中止了一個已建立的連接。這又是為什么呢?
uj5u.com熱心網友回復:
我也遇到了同樣的問題,不知道朋友解決了沒有?轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/112601.html
標籤:網絡通信
