高并发网络编程pdf(java高并发与网络编程实战)

http://www.itjxue.com  2023-02-10 18:16  来源:未知  点击次数: 

socket高并发网络编程服务端有什么框架?

netty;

PayServer.java

package com.miri.pay.scoket;

import io.netty.bootstrap.ServerBootstrap;

import io.netty.channel.ChannelFuture;

import io.netty.channel.ChannelInitializer;

import io.netty.channel.ChannelOption;

import io.netty.channel.ChannelPipeline;

import io.netty.channel.EventLoopGroup;

import io.netty.channel.nio.NioEventLoopGroup;

import io.netty.channel.socket.SocketChannel;

import io.netty.channel.socket.nio.NioServerSocketChannel;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

public class PayServer implements Runnable

{

private static final Logger DLOG = LoggerFactory.getLogger(PayServer.class);

private final int port;

public PayServer(int port)

{

this.port = port;

}

/**

* 为ServerBootstrap绑定指定端口

*/

public void run()

{

// 用于接收发来的连接请求

final EventLoopGroup bossGroup = new NioEventLoopGroup();

// 用于处理boss接受并且注册给worker的连接中的信息

final EventLoopGroup workerGroup = new NioEventLoopGroup();

try

{

// 配置服务器

final ServerBootstrap bootstrap = new ServerBootstrap();

bootstrap.group(bossGroup, workerGroup);

bootstrap.channel(NioServerSocketChannel.class);

bootstrap.option(ChannelOption.SO_BACKLOG, 128);

// 通过NoDelay禁用Nagle,使消息立即发出去,不用等待到一定的数据量才发出去

bootstrap.option(ChannelOption.TCP_NODELAY, true);

// 保持长连接状态

bootstrap.childOption(ChannelOption.SO_KEEPALIVE, true);

// CustomChannelInitializer是一个特殊的handler,用于方便的配置用户自定义的handler实现

bootstrap.childHandler(new CustomChannelInitializer());

// 绑定并开始接受传入的连接

final ChannelFuture future = bootstrap.bind(this.port).sync();

if (future.isSuccess())

{

PayServer.DLOG.info("Start the socket server {} success", this.port);

}

else

{

PayServer.DLOG.info("Start the socket server {} failure,System exit!", this.port);

throw new RuntimeException("Socket服务端启动失败");

}

// 等待服务器套接字关闭

// 关闭服务器

future.channel().closeFuture().sync();

}

catch (final InterruptedException e)

{

PayServer.DLOG.error("Close the socket server exception occurs,System exit!", e);

throw new RuntimeException("关闭Socket服务端失败");

}

finally

{

// 关闭所有事件循环终止线程

bossGroup.shutdownGracefully();

workerGroup.shutdownGracefully();

}

}

/**

* 特殊的内部类

* p

* 是一个特殊的handler,用于方便的配置用户自定义的handler实现

* @author xulonghui

*/

static class CustomChannelInitializer extends ChannelInitializerSocketChannel

{

@Override

protected void initChannel(SocketChannel ch) throws Exception

{

final ChannelPipeline p = ch.pipeline();

p.addLast(new PayMessageEncoder());

p.addLast(new PayMessageDecoder());

p.addLast(new PayServerHandler());

}

}

}

PayMessageEncoder.java

package com.miri.pay.scoket;

import io.netty.buffer.ByteBuf;

import io.netty.channel.ChannelHandlerContext;

import io.netty.handler.codec.MessageToByteEncoder;

import io.netty.util.CharsetUtil;

import com.miri.pay.model.CommonResponse;

import com.miri.pay.utils.JsonUtil;

/**

*消息编码器

* p

* 编码从服务端发送出的消息

*/

public class PayMessageEncoder extends MessageToByteEncoderCommonResponse

{

@Override

protected void encode(ChannelHandlerContext ctx, CommonResponse rsp, ByteBuf out) throws Exception

{

if (rsp != null)

{

final Object msgContent = rsp.getMsgContent();

// 消息ID,sequenceId和entityId三个加起来是12个长度

int msgLen = 12;

byte[] contentbs = new byte[] {};

if (msgContent != null)

{

final String content = JsonUtil.bean2json(msgContent);

contentbs = content.getBytes(CharsetUtil.UTF_8);

final int cl = contentbs.length;

msgLen += cl;

}

out.writeInt(msgLen);// 写入当前消息的总长度

out.writeInt(rsp.getMsgId());// 写入当前消息的消息ID

out.writeInt(rsp.getSequenceId());// 写入当前消息的SequenceId

out.writeInt(rsp.getEntityId());// 写入当前消息的EntityId

// 写入消息主体内容

if (contentbs.length 0)

{

out.writeBytes(contentbs);

}

}

}

}

PayMessageDecoder.java

package com.miri.pay.scoket;

import io.netty.buffer.ByteBuf;

import io.netty.channel.ChannelHandlerContext;

import io.netty.handler.codec.ByteToMessageDecoder;

import io.netty.util.CharsetUtil;

import java.util.List;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import com.miri.pay.constants.Constants;

import com.miri.pay.model.CommonRequest;

import com.miri.pay.utils.ByteUtil;

/**

* 消息解码器

* p

* 解码从客户端请求的消息

*/

public class PayMessageDecoder extends ByteToMessageDecoder

{

private static final Logger DLOG = LoggerFactory.getLogger(PayMessageDecoder.class);

/**

* 表示头长度的字节数

*/

private static final int HEAD_LENGTH = 4;

/**

* 所有ID串所属的字节数

*/

private static final int ID_STR_LENGTH = 12;

/**

* 单个ID所属的字节数

*/

private static final int SINGLE_ID_LENGTH = 4;

@Override

protected void decode(ChannelHandlerContext ctx, ByteBuf in, ListObject out) throws Exception

{

int readable = in.readableBytes();

if (readable PayMessageDecoder.HEAD_LENGTH)

{

return;

}

in.markReaderIndex(); // 我们标记一下当前的readIndex的位置

final int dataLength = in.readInt(); // 读取传送过来的消息的长度。ByteBuf 的readInt()方法会让他的readIndex增加4

if (dataLength 0)

{

// 我们读到的消息体长度为0,这是不应该出现的情况,这里出现这情况,关闭连接。

ctx.close();

}

readable = in.readableBytes();

if (readable dataLength)

{

// 读到的消息体长度如果小于我们传送过来的消息长度,则resetReaderIndex. 这个配合markReaderIndex使用的。把readIndex重置到mark的地方

in.resetReaderIndex();

return;

}

final byte[] body = new byte[dataLength];

in.readBytes(body);

// 判断是否读取到内容

final int length = body.length;

if (length == 0)

{

return;// 若未读出任何内容,则忽略

}

out.add(this.byte2req(body));

}

/**

* 将读取到的byte数据转换为请求对象

* @param body

* @return

* @throws Exception

*/

private CommonRequest byte2req(byte[] body) throws Exception

{

final CommonRequest req = new CommonRequest(Constants.INVALID_MSGID);

final int length = body.length;

// 若内容数组的长度小于或等于12,则表示消息主体内容为空,直接返回一个无效的消息出去

if (length PayMessageDecoder.ID_STR_LENGTH)

{

PayMessageDecoder.DLOG

.info("The client sends the message length is: {}, is invalid message, directly returns a msgId = {} request entity",

length, Constants.INVALID_MSGID);

return req;

}

// 获取消息ID

final byte[] mbs = new byte[PayMessageDecoder.SINGLE_ID_LENGTH];

System.arraycopy(body, 0, mbs, 0, PayMessageDecoder.SINGLE_ID_LENGTH);

final int msgId = ByteUtil.byte4toint(mbs);

req.setMsgId(msgId);

// 获取sequenceId

final byte[] sbs = new byte[PayMessageDecoder.SINGLE_ID_LENGTH];

System.arraycopy(body, 4, sbs, 0, PayMessageDecoder.SINGLE_ID_LENGTH);

final int sequenceId = ByteUtil.byte4toint(sbs);

req.setSequenceId(sequenceId);

// 获取entityId

final byte[] ebs = new byte[PayMessageDecoder.SINGLE_ID_LENGTH];

System.arraycopy(body, 8, ebs, 0, PayMessageDecoder.SINGLE_ID_LENGTH);

final int entityId = ByteUtil.byte4toint(ebs);

req.setEntityId(entityId);

// 获取消息主体内容

if (length PayMessageDecoder.ID_STR_LENGTH)

{

final int contentLen = length - PayMessageDecoder.ID_STR_LENGTH;

final byte[] contentbs = new byte[contentLen];

System.arraycopy(body, 12, contentbs, 0, contentLen);

final String content = new String(contentbs, CharsetUtil.UTF_8);

req.setMsgContent(content);

}

return req;

}

}

PayServerHandler.java

package com.miri.pay.scoket;

import io.netty.channel.Channel;

import io.netty.channel.ChannelHandlerContext;

import io.netty.channel.ChannelInboundHandlerAdapter;

import io.netty.util.ReferenceCountUtil;

import java.util.HashMap;

import java.util.Map;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import com.miri.pay.MessageQueue;

import com.miri.pay.model.CommonRequest;

import com.miri.pay.model.PendingBean;

/**

* Socket服务端处理器

*/

public class PayServerHandler extends ChannelInboundHandlerAdapter

{

private static final Logger DLOG = LoggerFactory.getLogger(PayServerHandler.class);

/**

* 外部订单号-频道

*/

public static final MapString, Channel CHANNELS = new HashMapString, Channel();

@Override

public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception

{

try

{

PayServerHandler.DLOG.info("Client send to msg is: {}", msg);

final CommonRequest request = (CommonRequest) msg;

final PendingBean bean = new PendingBean(ctx.channel(), request);

MessageQueue.offer(bean);

}

finally

{

ReferenceCountUtil.release(msg);

}

}

@Override

public void channelReadComplete(ChannelHandlerContext ctx) throws Exception

{

ctx.flush();

}

@Override

public void channelActive(ChannelHandlerContext ctx) throws Exception

{

super.channelActive(ctx);

final Channel channel = ctx.channel();

PayServerHandler.DLOG.info("Client active form {}", channel.remoteAddress());

}

@Override

public void channelInactive(ChannelHandlerContext ctx) throws Exception

{

super.channelInactive(ctx);

final Channel channel = ctx.channel();

PayServerHandler.DLOG.info("Client inactive form {}", channel.remoteAddress());

}

@Override

public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception

{

PayServerHandler.DLOG.error("System exception", cause);

ctx.close();

}

}

《UNIX网络编程卷1套接字联网API第3版》pdf下载在线阅读全文,求百度网盘云资源

《UNIX网络编程卷1套接字联网API第3版》百度网盘pdf最新全集下载:

链接:

?pwd=riwe 提取码:riwe

简介:UNIX网络编程卷1套接字联网API第3版全面深入地介绍了如何使用套接字API进行网络编程。全书不但介绍了基本编程内容,还涵盖了与套接字编程相关的高级主题,对于客户/服务器程序的各种设计方法也作了完整的探讨,最后还深入分析了流这种设备驱动机制。 ?

《Python网络编程基础》pdf下载在线阅读全文,求百度网盘云资源

《python网络编程基础》百度网盘pdf最新全集下载:

链接:

?pwd=c8d1 提取码:c8d1

简介:25年前,世界和现在是完全不同的。很少人能有机会和大洋彼岸的人谈话。寄一封信需要好几周的时间。收听外国的短波新闻广播除了需要专门的技术和耐心外,还要非常好的气候条件。而今天,收到来自韩国的E-mail、查看加利福尼亚的天气,以及阅读德国当天的头条新闻对我们来说都是很平常的事情,而且都可以在五分钟之内完成。压缩文件在互联网上的传输使得我们可以做很多事情,从管理投资账户到观看远房亲戚的照片。

尽管Internet已经有25年的历史了,但它还是处在幼年阶段。作为一种新技术,它还在逐渐成长。

我写这本书的原因是因为Internet是那么地让人兴奋。在过去的几年中,我们看到了整个行业的增长,而这些是以前没有的。同时互联网也是产生大量发明家的地方。

而且这也是我希望您从本书获得的,我希望这本书能成为您的实验手册--您为了使Internet更美好而进行发明创造的指南。 ?

《Android4.0网络编程详解》pdf下载在线阅读,求百度网盘云资源

《Android 4.0网络编程详解》(王家林)电子书网盘下载免费在线阅读

资源链接:

链接:

?提取码:6shy?? ?

书名:Android 4.0网络编程详解

作者:王家林

出版社:电子工业出版社

出版年份:2012-1

页数:374

内容简介:《Android 4.0网络编程详解》对Android 4.0网络编程中的XML形式,JSON操作,需要掌握的HTTP知识,数据下载/上传,Socket编程,浏览器开发,Android中软件界面设计新大陆——采用HTML设计软件界面,Android应用程序的生命周期等内容进行了深入的讲解。

(责任编辑:IT教学网)

更多

推荐浏览器文章