dreammark 2011-07-08 14:04
浏览 278
已采纳

mina疑问,请各位大神帮忙

公司项目,要求定时去采集器采集数据,采集器内置socket服务器,现在我用mina短连接,每次都可以收到数据
但是用tcp查看器查看有好多的 [System Process] TIME_WAIT,而且是越来越多
代码如下:


import java.net.InetSocketAddress;
import java.util.concurrent.TimeUnit;

import org.apache.mina.core.RuntimeIoException;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.future.ReadFuture;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.transport.socket.SocketSessionConfig;
import org.apache.mina.transport.socket.nio.NioSocketConnector;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.xmgsd.utils.DESPlus;

/**

  • @author mjzhang
  • @version 创建时间:2011-6-20 上午11:49:17 */

public class RoomMonitorClent {
private static final Logger log = LoggerFactory.getLogger(RoomMonitorClent.class);
private String host;
private int port;

NioSocketConnector connector;
public RoomMonitorClent(String host, int port) {
this.host = host;
this.port = port;
init();
}

public void init() {
        connector = new NioSocketConnector();
       connector.setConnectTimeoutMillis(30000L);
      // connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new YourCodecFactory()));
       SocketSessionConfig cfg = connector.getSessionConfig();
       cfg.setUseReadOperation(true);
}

/**
 * 
 * @param msg
 * @return
 */
public String sendMessage(String msg) {
     InetSocketAddress addr = new InetSocketAddress(host,port);
       IoSession session = null;
       try {
           session = connector.connect(addr).awaitUninterruptibly().getSession();
           connector.getSessionConfig().setSoLinger(0);
            IoBuffer buffer = IoBuffer.allocate(100, true);// 分清楚direct和heap方式的缓冲区别
            buffer.setAutoExpand(true);// 自动扩张
            buffer.setAutoShrink(true);// 自动收缩
            buffer.put(DESPlus.hexStr2ByteArr(msg));
            buffer.flip();
            buffer.free();
              // 发送
              session.write(buffer).awaitUninterruptibly();
              // 接收
              ReadFuture readFuture = session.read();
              if (readFuture.awaitUninterruptibly(500, TimeUnit.MILLISECONDS)) {
                  IoBuffer result = (IoBuffer)readFuture.getMessage();
                  System.out.println("收到服务器发来的信息: " + result);
                //返回的信息字符串
                 return result.getHexDump().replace(" ", "");
                  // TODO 处理消息

              } else {
                  // 读超时
                  System.out.println("向服务器:"+host+":"+port+"发送命令:"+msg+"未响应,读取超时,请确定该设备正常运行!");
                  log.error("向服务器:"+host+":"+port+"发送命令:"+msg+"未响应,读取超时,请确定该设备正常运行!");
                  return null;
              }

           } 
       catch (RuntimeIoException e) {
            System.out.println("服务器:" + host + ":" + port + "未能连接!");
        }
       catch (Exception e) {
        // TODO: handle exception

           e.printStackTrace();
    }
       finally {
              // 断开
           if(session != null){
              session.close(true);
              //session.getService().dispose();
              connector.dispose();
           }
           }
    return null;
}




/**
 * 根据返回结果获取温度
 * @param strinput
 * @return
 */
public static String getTemperature(String strinput)
{
    String temperature = null;
    if (strinput.length()==18&&strinput.substring(0, 2).equals("01")) 
    {
        //以下是温度计算
        String tmp1=strinput.substring(6, 8);
        String tmp2=strinput.substring(8, 10);
        int tmp3=Integer.valueOf(tmp1,16);
        int tmp4 = Integer.valueOf(tmp2,16);
        temperature=""+(float)(tmp3*256+tmp4)/10;
        //System.out.println("温度是:"+(float)(tmp3*256+tmp4)/10+"℃");
    }
    return temperature;
}

/**
 * 根据返回结果获取湿度
 * @param strinput
 * @return
 */
public static String getHumidity(String strinput)
{
    String humidity=null;
    if (strinput.length()==18&&strinput.substring(0, 2).equals("01")) 
    {
        //以下是湿度计算
        String _tmp1=strinput.substring(10, 12);
        String _tmp2=strinput.substring(12, 14);
        int _tmp3=Integer.valueOf(_tmp1,16);
        int _tmp4 = Integer.valueOf(_tmp2,16);
        humidity = (float)(_tmp3*256+_tmp4)/10+"";
        //System.out.println("湿度是:"+(float)(_tmp3*256+_tmp4)/10+"%");
    }
    return humidity;
}


public static void main(String[] args) throws Exception {


    for (int i = 0; i < 10; i++) {
        RoomMonitorClent clent = new RoomMonitorClent("192.168.0.250",27011);

// clent.sendMessage("0203000300023438");
String s = clent.sendMessage("010300030002340B");
System.out.println(s);
}
}

}



如果用长连接的话 如何去做?

  • 写回答

3条回答 默认 最新

  • taolei 2011-07-09 18:00
    关注

    长连接就是只要客户端程序不退出,连接不出异常,你就一直用同一个连接发送数据,不要每次发送都去创建新的连接。

    如果用短连接的话,通常客户端都会有一个连接池用于复用这些连接。例如JDK的HTTP支持。频繁地创建和关闭连接操作系统受不了,原因上面解释得很到位了。

    我再这说句可能许多人都不愿意听的话,包括有几年工作经验的很多人都太迷信JavaNIO了。没有几百个连接以上完全没必要用NIO。其实你这种需求用BIO做几行代码就搞定了,又清晰又简单,看看Java入门书籍就能做到,完全没必要去搞什么MINA。
    如果学过MINA的话,学BIO更容易,和MINA的IOFilter机制很像,BIO可以在Input/Output上附加各种机制,而且更简单,甚至一行代码就能搞定。例如:
    [code="java"]
    BufferedReader in = new BufferedReader(new InputStreamReader(new BufferedInputStream(sock.getInputStream())));
    for(;;)
    {
    String msg = in.readLine();
    if(msg == null)//end of stream
    break;
    processMessage(msg);
    }
    in.close();//省略了异常处理机制
    sock.close();//实际代码中要处理异常

    boolean autoFlush = true;
    

    PrintWriter out = new PrintWriter(new BufferedOutputStream(sock.getOutputStream()),autoFlush);
    public void sendMessage(String msg) throws IOException
    {
    synchronized(out)
    {
    out.println(msg);
    }
    }
    [/code]
    这段代码是直接打出来的,如果有语法错误请自行修改。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 关于vue2中methods使用call修改this指向的问题
  • ¥15 idea自动补全键位冲突
  • ¥15 请教一下写代码,代码好难
  • ¥15 iis10中如何阻止别人网站重定向到我的网站
  • ¥15 滑块验证码移动速度不一致问题
  • ¥100 栈回溯相关,模块加载后KiExceptionDispatch无法正常回溯了
  • ¥15 Utunbu中vscode下cern root工作台中写的程序root的头文件无法包含
  • ¥15 麒麟V10桌面版SP1如何配置bonding
  • ¥15 Marscode IDE 如何预览新建的 HTML 文件
  • ¥15 K8S部署二进制集群过程中calico一直报错