手游开发中网络通信使用长连接还是短连接比较好用的手游模拟器

主题信息(必填)
主题描述(最多限制在50个字符)
申请人信息(必填)
申请信息已提交审核,请注意查收邮件,我们会尽快给您反馈。
如有疑问,请联系
CSDN &《程序员》编辑/记者,投稿&纠错等事宜请致邮
你只管努力,剩下的交给时光!
如今的编程是一场程序员和上帝的竞赛,程序员要开发出更大更好、傻瓜都会用到软件。而上帝在努力创造出更大更傻的傻瓜。目前为止,上帝是赢的。个人网站:。个人QQ群:、
人生得意须尽欢,莫使金樽空对月。博客访问: 819621
博文数量: 1789
注册时间:
ITPUB论坛APP
ITPUB论坛APP
APP发帖 享双倍积分
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: Linux
有一个JAVA系统,系统的几个进程间有大量的数据传送,基于的是TCP连接。这个系统在小压力的情况下工作正常,但是处理能力一直上不去。最近对这个系统进行压力测试,在进程间发送数据时出现exception : Address already in use: connect。查发送数据的源代码,发现发送者采用的是短连接模型--每次发送时,都重新与接收者建立新连接。于是立即修改发送侧代码为长连接方式,并重做压力测试,结果没有再出现这个异常,而且CPU占用率也降下来了一截。如果理解TCP/IP连接的原理,对于在短连接方式下异常出现的原因也就不足为怪了:每次发送时,client都建立连接,发送完毕就断开连接。断开连接是要花一些时间的。如果再次发起连接太快,可能会由于资源未准备好而失败。测试时是在WINDOWS平台上进行的,于是从MSDN上贴了一段错误解释:connect()WSAEADDRINUSE The socket's local address is already in use and the socket was not marked to allow address reuse with SO_REUSEADDR. This error usually occurs when executing bind, but could be delayed until this function if the bind was to a partially wildcard address (involving ADDR_ANY) and if a specific address needs to be committed at the time of this function.
阅读(736) | 评论(0) | 转发(0) |
相关热门文章
给主人留下些什么吧!~~
请登录后评论。长连接、短连接、长轮询和WebSocket-前端开发博客
推荐文章 8236Views 2665Views 12027Views 1441Views 725Views热门文章
3,836Views
2,508Views
2,437Views
2,397Views
2,251Views
2,106Views
对这篇文章不满意吗?百度搜索:");用SOCKET通信时一般什么时候用长连接,什么时候用短连接-CSDN论坛
用SOCKET通信时一般什么时候用长连接,什么时候用短连接
长连接是不是就是一直保持连接,发送接受数据.
短连接就是发送好后断开.
两种方式有什么优缺点吗?
如果程序需要不定时的传送数据,并且有可能出现传送忙时,就采用长连接;反之采用短连接
一切从应用出发,理论可以列出一堆!
只要你应用中遇到了,只要你不笨,想象就知道了
如果你的程序发包频率很高,可以考虑用长连接
如果你的程序客户端很少,可以考虑用长连接,否则相反
如果通信线路不稳定,多用短连接
局域网多用长连接,广域网多有短连接
长连接的话对服务器端的程序要求比较高
如果有很多个客户端的话,每个客户端都和服务器端长连接就会占用服务器端的很多资源
短连接的话由于每次都要和服务器端建立连接
所以通讯起来如果发包频率高的话就会影响速度
回复博客分类:
Apache MINA是Apache组织的一个优秀的项目。MINA是Multipurpose Infrastructure for NetworkApplications的缩写。它是一个网络应用程序框架,用来帮助用户非常方便地开发高性能和高可靠性的网络应用程序。在本文中介绍了 如何通过Apache Mina2.0来实现TCP协议长连接和短连接应用。
2、系统介绍
2.1系统框架
整个系统由两个服务端程序和两个客户端程序组成。分别实现TCP长连接和短连接通信。
系统业务逻辑是一个客户端与服务端建立长连接,一个客户端与服务端建立短连接。数据从短连接客户端经过服务端发送到长连接客户端,并从长连接客户端接收响应数据。当收到响应数据后断开连接。
系统架构图如下:
2.2处理流程
系统处理流程如下:
启动服务端程序,监听端口。
长连接客户端向服务端8002端口建立连接,服务端将连接对象保存到共享内存中。由于采用长连接方式,连接对象是唯一的。
短连接客户端向服务端8001端口建立连接。建立连接后创建一个连接对象。
短连接客户端连接成功后发送数据。服务端接收到数据后从共享内存中得到长连接方式的连接对象,使用此对象向长连接客户端发送数据。发送前将短连接对象设为长连接对象的属性值。
长连接客户端接收到数据后返回响应数据。服务端从长连接对象的属性中取得短连接对象,通过此对象将响应数据发送给短连接客户端。
短连接客户端收到响应数据后,关闭连接。
3、服务端程序
3.1长连接服务端
public class MinaLongConnServer {
private static final int PORT = 8002;
public void start()throws IOException{
IoAcceptor acceptor = new NioSocketAcceptor();
acceptor.getFilterChain().addLast("logger", new LoggingFilter());
acceptor.getFilterChain().addLast("codec", newProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));
acceptor.setHandler(new MinaLongConnServerHandler());
acceptor.getSessionConfig().setReadBufferSize(2048);
acceptor.bind(new InetSocketAddress(PORT));
System.out.println("Listeningon port " + PORT);
public class MinaLongConnServerHandler extends IoHandlerAdapter {
private final Logger logger = (Logger) LoggerFactory.getLogger(getClass());
public void sessionOpened(IoSession session) {
InetSocketAddress remoteAddress = (InetSocketAddress)session.getRemoteAddress();
String clientIp = remoteAddress.getAddress().getHostAddress();
("LongConnect Server opened Session ID ="+String.valueOf(session.getId()));
("接收来自客户端 :" + clientIp + "的连接.");
Initialization init = Initialization.getInstance();
HashMap&String, IoSession& clientMap =init.getClientMap();
clientMap.put(clientIp, session);
public void messageReceived(IoSession session, Object message) {
("Messagereceived in the long connect server..");
String expression = message.toString();
("Message is:" + expression);
IoSession shortConnSession =(IoSession) session.getAttribute("shortConnSession");
("ShortConnect Server Session ID ="+String.valueOf(shortConnSession.getId()));
shortConnSession.write(expression);
public void sessionIdle(IoSession session, IdleStatus status) {
("Disconnectingthe idle.");
// disconnect an idle client
session.close(true);
public void exceptionCaught(IoSession session, Throwable cause) {
// close the connection onexceptional situation
logger.warn(cause.getMessage(), cause);
session.close(true);
3.2短连接服务端
public class MinaShortConnServer {
private static final int PORT = 8001;
public void start()throws IOException{
IoAcceptor acceptor = new NioSocketAcceptor();
acceptor.getFilterChain().addLast("logger", new LoggingFilter());
acceptor.getFilterChain().addLast("codec", newProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));
acceptor.setHandler(new MinaShortConnServerHandler());
acceptor.getSessionConfig().setReadBufferSize(2048);
acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 3);
acceptor.bind(new InetSocketAddress(PORT));
System.out.println("Listeningon port " + PORT);
public class MinaShortConnServerHandler extends IoHandlerAdapter {
private final Logger logger = (Logger) LoggerFactory.getLogger(getClass());
public void sessionOpened(IoSession session) {
InetSocketAddress remoteAddress = (InetSocketAddress)session.getRemoteAddress();
(remoteAddress.getAddress().getHostAddress());
(String.valueOf(session.getId()));
public void messageReceived(IoSession session, Object message) {
("Messagereceived in the short connect server...");
String expression = message.toString();
Initialization init = Initialization.getInstance();
HashMap&String, IoSession& clientMap =init.getClientMap();
if (clientMap == null || clientMap.size() == 0) {
session.write("error");
IoSession longConnSession = null;
Iterator&String& iterator =clientMap.keySet().iterator();
String key = "";
while (iterator.hasNext()) {
key = iterator.next();
longConnSession = clientMap.get(key);
("ShortConnect Server Session ID :"+String.valueOf(session.getId()));
("LongConnect Server Session ID :"+String.valueOf(longConnSession.getId()));
longConnSession.setAttribute("shortConnSession",session);
longConnSession.write(expression);
public void sessionIdle(IoSession session, IdleStatus status) {
("Disconnectingthe idle.");
// disconnect an idle client
session.close(true);
public void exceptionCaught(IoSession session, Throwable cause) {
// close the connection onexceptional situation
logger.warn(cause.getMessage(), cause);
session.close(true);
4、客户端程序
4.1长连接客户端
使用java.net.Socket来实现向服务端建立连接。Socket建立后一直保持连接,从服务端接收到数据包后直接将原文返回。
public class TcpKeepAliveClient {
private int
private static Socket socket = null;
private static int timeout = 50 * 1000;
public TcpKeepAliveClient(String ip, int port) {
this.port =
public void receiveAndSend() throws IOException {
InputStream input = null;
OutputStream output = null;
if (socket == null || socket.isClosed() || !socket.isConnected()) {
socket = new Socket();
InetSocketAddress addr = new InetSocketAddress(ip, port);
socket.connect(addr, timeout);
socket.setSoTimeout(timeout);
System.out.println("TcpKeepAliveClientnew ");
input = socket.getInputStream();
output = socket.getOutputStream();
// read body
byte[] receiveBytes = {};// 收到的包字节数组
while (true) {
if (input.available() & 0) {
receiveBytes = new byte[input.available()];
input.read(receiveBytes);
System.out.println("TcpKeepAliveClientsend date :" + new String(receiveBytes));
output.write(receiveBytes, 0, receiveBytes.length);
output.flush();
} catch (Exception e) {
e.printStackTrace();
System.out.println("TcpClientnew socket error");
public static void main(String[] args) throws Exception {
TcpKeepAliveClient client = new TcpKeepAliveClient("127.0.0.1", 8002);
client.receiveAndSend();
4.2短连接客户端
public class MinaShortClient {
private static final int PORT = 8001;
public static void main(String[] args) throws IOException,InterruptedException {
IoConnector connector = new NioSocketConnector();
connector.getSessionConfig().setReadBufferSize(2048);
connector.getFilterChain().addLast("logger", new LoggingFilter());
connector.getFilterChain().addLast("codec", newProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));
connector.setHandler(new MinaShortClientHandler());
for (int i = 1; i &= 10; i++) {
ConnectFuture future = connector.connect(new InetSocketAddress("127.0.0.1", PORT));
future.awaitUninterruptibly();
IoSession session =future.getSession();
session.write(i);
session.getCloseFuture().awaitUninterruptibly();
System.out.println("result=" + session.getAttribute("result"));
connector.dispose();
public class MinaShortClientHandler extends IoHandlerAdapter{
private final Logger logger = (Logger) LoggerFactory.getLogger(getClass());
public MinaShortClientHandler() {
public void sessionOpened(IoSession session) {
public void messageReceived(IoSession session, Object message) {
("Messagereceived in the client..");
("Message is:" + message.toString());
session.setAttribute("result", message.toString());
session.close(true);
public void exceptionCaught(IoSession session, Throwable cause) {
session.close(true);
通过本文中的例子,Apache Mina在服务端可实现TCP协议长连接和短连接。在客户端只实现了短连接模式,长连接模式也是可以实现的(在本文中还是采用传统的java Socket方式)。两个服务端之间通过共享内存的方式来传递连接对象也许有更好的实现方式。
lz 你的两个messageReceived方法是不是错乱了?
可否提供一个客户端长连接的例子,以参考学习 可否提供一个利用mina建立长连接的客户端的例子,以参考学习
smallbee 写道红发programmer 写道smallbee 写道&&&&&&&&&& 红发programmer 写道smallbee 写道红发programmer 写道请教下,如何利用mina建立长连接的客户端。
我尝试了很多次,但都有很大的问题。。。
思路就是连接上来,然后把iosession保留在后台单例下 ,这样就可以实现长连接。
可是,我使用短连接的时候,每次它都会阻塞在session.getCloseFuture().awaitUninterruptibly();
不再往下运行,很苦恼。。。
你不是要实现长连接么?如果是长连接,就是阻塞的。
我按照您的socket长连接客户端的例子,但是你每次只是发送接收到的按个byte[]。有没有办法发送自己定义的byte[],我试了几次,服务器可以接受,但是无法处理自己发送的byte[]。
无法处理时什么意思?服务器可以接收到,说明通信是没有问题的,注意你的编码方式。
很感谢你耐心的回答,现在我遇到另一个问题,就是当我的字符串长度为113的时候,发送的消息是可以被服务器处理的,超过这个长度,服务器的Iohandler就无法处理了。这是怎么回事呢?我用了mina自带的Text的那个过滤器。
没用过mina自带的Text的那个过滤器,我们是自己写的。因为socket是无边界的,所以需要你在自己的报文结构中(一般在前面)指定我们传输的报文长度,然后往后面截取即可。
红发programmer 写道smallbee 写道&&&&&&&&&& 红发programmer 写道smallbee 写道红发programmer 写道请教下,如何利用mina建立长连接的客户端。我尝试了很多次,但都有很大的问题。。。思路就是连接上来,然后把iosession保留在后台单例下 ,这样就可以实现长连接。可是,我使用短连接的时候,每次它都会阻塞在session.getCloseFuture().awaitUninterruptibly();不再往下运行,很苦恼。。。你不是要实现长连接么?如果是长连接,就是阻塞的。我按照您的socket长连接客户端的例子,但是你每次只是发送接收到的按个byte[]。有没有办法发送自己定义的byte[],我试了几次,服务器可以接受,但是无法处理自己发送的byte[]。无法处理时什么意思?服务器可以接收到,说明通信是没有问题的,注意你的编码方式。很感谢你耐心的回答,现在我遇到另一个问题,就是当我的字符串长度为113的时候,发送的消息是可以被服务器处理的,超过这个长度,服务器的Iohandler就无法处理了。这是怎么回事呢?我用了mina自带的Text的那个过滤器。
smallbee 写道&&&&&&&&&& 红发programmer 写道smallbee 写道红发programmer 写道请教下,如何利用mina建立长连接的客户端。
我尝试了很多次,但都有很大的问题。。。
思路就是连接上来,然后把iosession保留在后台单例下 ,这样就可以实现长连接。
可是,我使用短连接的时候,每次它都会阻塞在session.getCloseFuture().awaitUninterruptibly();
不再往下运行,很苦恼。。。
你不是要实现长连接么?如果是长连接,就是阻塞的。
我按照您的socket长连接客户端的例子,但是你每次只是发送接收到的按个byte[]。有没有办法发送自己定义的byte[],我试了几次,服务器可以接受,但是无法处理自己发送的byte[]。
无法处理时什么意思?服务器可以接收到,说明通信是没有问题的,注意你的编码方式。
&&&&&&&&&& 红发programmer 写道smallbee 写道红发programmer 写道请教下,如何利用mina建立长连接的客户端。我尝试了很多次,但都有很大的问题。。。思路就是连接上来,然后把iosession保留在后台单例下 ,这样就可以实现长连接。可是,我使用短连接的时候,每次它都会阻塞在session.getCloseFuture().awaitUninterruptibly();不再往下运行,很苦恼。。。你不是要实现长连接么?如果是长连接,就是阻塞的。我按照您的socket长连接客户端的例子,但是你每次只是发送接收到的按个byte[]。有没有办法发送自己定义的byte[],我试了几次,服务器可以接受,但是无法处理自己发送的byte[]。
smallbee 写道红发programmer 写道请教下,如何利用mina建立长连接的客户端。
我尝试了很多次,但都有很大的问题。。。
思路就是连接上来,然后把iosession保留在后台单例下 ,这样就可以实现长连接。
可是,我使用短连接的时候,每次它都会阻塞在session.getCloseFuture().awaitUninterruptibly();
不再往下运行,很苦恼。。。
你不是要实现长连接么?如果是长连接,就是阻塞的。
红发programmer 写道请教下,如何利用mina建立长连接的客户端。我尝试了很多次,但都有很大的问题。。。思路就是连接上来,然后把iosession保留在后台单例下 ,这样就可以实现长连接。可是,我使用短连接的时候,每次它都会阻塞在session.getCloseFuture().awaitUninterruptibly();不再往下运行,很苦恼。。。
请教下,如何利用mina建立长连接的客户端。
我尝试了很多次,但都有很大的问题。。。
思路就是连接上来,然后把iosession保留在后台单例下 ,这样就可以实现长连接。
浏览: 181674 次
来自: 杭州
xin_jmail 写道首先感谢楼主的文章,让我知道了lock ...
首先感谢楼主的文章,让我知道了lock.newConditio ...
brad2309 写道lz 你的两个messageReceiv ...
lz 你的两个messageReceived方法是不是错乱了
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'}

我要回帖

更多关于 网络通信连接设备 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信