//strMsg,iRet,strStra均为全局变量
 public  int SendPackage(String parm_1,String host,String parm_2,String
parm_3){
   Socket socket = null;      //Socket连接
   BufferedReader in =null;   //读入数据缓冲区
   PrintWriter out =null;     //输出数据缓冲区
   int StrHead = 0;           //要过滤掉的信息头
   try{       String s2 = null;
       s2 = "02|"+parm_1+"|"+parm_2+"|"parm_3+"|";
       String hostIP=host.split(":")[0];
       int port 
=Integer.parseInt(host.split(":")[1]==null?"0":host.split
(":")[1]);
       socket = new Socket(hostIP,port);
       socket.setSoTimeout(30000);
       in = new BufferedReader(new  
InputStreamReader(socket.getInputStream
()));
       out = new PrintWriter(socket.getOutputStream());
       out.print(s2);
        out.flush();
        String s1 = null;
        s1 = in.readLine();
        StringTokenizer st = new StringTokenizer(s1,"|");
        if (st.hasMoreTokens())
            StrHead = Integer.parseInt(st.nextToken());
        if (st.hasMoreTokens())
            iRet = Integer.parseInt(st.nextToken());
        if (iRet==0){
        if (st.hasMoreTokens());
            strMsg = st.nextToken();
        if (st.hasMoreTokens());
        ;
        if (st.hasMoreTokens());
            strStra=st.nextToken();
        }else if (iRet==-1){
             if (st.hasMoreTokens());
                 strMsg = st.nextToken();
        }else if(iRet==1){
             if (st.hasMoreTokens())
                strMsg = st.nextToken();
        }        in.close();
        out.close();
        socket.close();
       }catch(SocketException e1){
            iRet=-1;
            strMsg="主机无响应";
        }catch(Exception e2){
            iRet = 1;
            strMsg="其他失败";
        }       return iRet;
}请大家帮我看看这样的程序结构(比如try...)合理吗,能否再有优化呢?
另外实际测试中我发现两个问题:
1.若连接建立成功后,此程序等待服务器端返传的信息,当超时值30秒到达时,程序
依然会去读取in.readLine(); 但如果这个时候服务器端未返传任何信息,则
s1=in.readLine();语句依然会执行(我的本意是超时以后执行socketException里的语
句)。而此时s1等于什么呢?
NULL吗?因为后面有s1的字符串处理,是不是因为s1为null就会直接跳到exception里
了呢?2.现在利用此程序与VB写的服务器端通信(另一位同仁写的),而他的程序设置了最多
只处理2000个连接(据说vb的处理机制是侦听到一个连接请求,就新开一个socekt线程
去处理)。现在我想请问一下,如果当vb端的连接数到达2000以后,我用这个程序发包
过去,会执行哪部分代码呢?还是说我的程序根本就没有做相应的处理。请大家看看
我的代码有没有遗漏的地方。分数不够绝对可以再追加,几百上千都无问题,现在客户使用此程序时,出现了
strMsg='其他失败'以及strMsg=null 
这样的两个问题。。我找不到原因,而现在又在
外地出差,一时没有测试环境,只好上来请教各位了。~

解决方案 »

  1.   

    出了异常要看堆栈的,你catch住异常之后没有打出来,很难判断原因
      

  2.   

    超时的话,抛出的是java.net.SocketTimeoutException异常,并不会执行socketException
      

  3.   

    TO  pxboy(阿土仔) :
    我倒是想过调用 e.getMessage 来显示异常信息,但现在是希望各位大侠帮忙分析下这段代码还可能会出现哪些类型的异常呢?我自己的Exception太笼统了,的确影响错误分析。TO xiaohuasz() :
    其实我的代码在实际执行时,如果建立Socket的时候超过30秒,就会跳转到socketException。
    但我现在不理解的是:当连接建立起来后,如果对方到了30秒还没有返回信息,这时候程序为什么还是会去执行 s1=in.readLine(); 呢? 难道Socket通讯机制就是如此吗?
      

  4.   

    到底什么异常你用printStackTrace()打出来看一下不就知道了吗?把异常输出贴上来看看,大家才能帮你啊
      

  5.   

    1.timeout本来就是因为readline的操作计时触发的,
    可以优化的地方很多,你把信息分拆这种业务操作和通讯接口都封装到一起了,代码几乎不可重用了,而且严重影响多线程并发的效率,因为io是费时(不定时长)操作,而信息分拆是固定时长的。
    另外既然你自己定义了异常信息哪就应该细分catch的异常类型,另外加上printstacktrack语句打印明细
    2.其他失败和strMSG=null明显是由于信息分拆段造成的,建议跟综数据包详细信息和分拆结果. 
      

  6.   

    BufferedReader读数据流有点问题,如果最后一个字符不是换行符的话,
    会等半天。
    但实际上数据已经传完了。
    最后的Exception估计是IOException,
    是远端中断socket连接导致的。
      

  7.   

    哎,各位大大,这段代码是我第一次写的JAVA程序,实际上我学习JAVA总计时间还不到30小时。
    代码的完成一部分靠自己delphi经验,一部分是网上借鉴的例子。我的任务是写一个这样的类,完成所有数据的通讯。现在我最头痛的就是如何能把上面代码中会出现的所有异常类型都细分出来,及时捕捉,然后解释成各种明确的错误信息(直接提交给普通用户),并存放在strMsg中。请问printStackTrace()信息内容是不是通常都很多?由于诸多原因的限制,我无法将printStackTrace()的大量信息存放在任何位置,最多只能截取其中的一部分内容所以在日后的故障排查时,只能依赖
      

  8.   

    请问printStackTrace()信息内容是不是通常都很多?由于诸多原因的限制,我无法将printStackTrace()的大量信息存放在任何位置,最多只能截取其中的一部分内容,然后再加上用户能看懂的错误提示,一起存放在strMsg中。但是截取哪些内容才是最关键的??目前用户最想要的,就是每次数据传输时的出错信息(strMsg的内容)要明朗,易懂,不能再是“其他失败”这样含糊的概念了。时间紧迫,请大家都敲点字,帮帮我啊~~ 不然BOSS要k我了