belief1117 2012-07-25 20:45
浏览 413
已采纳

socket connection resect

我写了一个传送报文的socket,正常情况下服务器端和客户端都没有问题,但是只要客户端在报错,服务器端就会报connection reset,理论上客户端的操作应该对服务器端没有影响才对啊
server
[code="java"]
package Work;

import java.io.*;
import java.net.*;
import java.util.HashMap;

public class SocketAPIServer extends Thread {
/**
* 报文拆解 返回报文体中的字段
*
* @param rspPkgStr
* 返回报文
* @return
* @throws Exception
*/
public static HashMap dissolveRspPkgBodyStr(String rspPkgStr)
throws Exception {
HashMap hashMap = new HashMap();

    String sbody = rspPkgStr.substring(65);

    String[] abody = sbody.split("\\|");

    for (int i = 0; i < abody.length; i++) {
        String sPair = abody[i];
        String[] aPair = sPair.split("=");
        if (aPair.length == 2) {
            hashMap.put(sPair.split("=")[0], sPair.split("=")[1]);
        } else {
            hashMap.put(sPair.split("=")[0], "");
        }
    }

    return hashMap;
}

/**
 * 报文拆解 返回报文头中的字段
 * 
 * @param rspPkgStr
 * @return
 * @throws Exception
 */
public static HashMap<String, String> dissolvePkgHeadStr(String rspPkgStr)
        throws Exception {

    HashMap<String, String> hashMap = new HashMap<String, String>();

    String shead = rspPkgStr.substring(0, 65);

    hashMap.put("报文长度", shead.substring(0, 5)); // 0-5_报文长度
    hashMap.put("ID号", shead.substring(5, 11)); // 6-11_ID号
    hashMap.put("固定'0000'", shead.substring(11, 15)); // 12-15_固定"0000"
    hashMap.put("交易码", shead.substring(15, 25)); // 16-25_六个字符串的交易码
    hashMap.put("客户经理号", shead.substring(25, 33)); // 26-33_客户经理号
    hashMap.put("空格_01", shead.substring(33, 54)); // 34-54_空格
    hashMap.put("空格_02", shead.substring(54, 65)); // 55-64空格

    return hashMap;

}

/**
 * 建立socket连接,监听端口
 * 
 * @return
 */
public void run() {
    ServerSocket serverSocket = null;
    PrintWriter out = null;
    BufferedReader in = null;
    try {
        // 实例化监听端口
        serverSocket = new ServerSocket(8888);
    } catch (IOException e) {
        System.err.println("Could not listen on port: 8888.");
        System.exit(1);
    }
    Socket incoming = null;
    try {
        while (true) {
            try {
                incoming = serverSocket.accept();
                out = new PrintWriter(incoming.getOutputStream(), true);
                // 先将字节流通过 InputStreamReader 转换为字符流,之后将字符流放入缓冲之中
                in = new BufferedReader(new InputStreamReader(incoming
                        .getInputStream()));
            } catch (IOException e) {
                e.printStackTrace();
            }

            // 提示信息
            out.println("Hello! . . . ");
            out.flush();
            // 没有异常的情况不断循环
            while (true)
            {
                // 只有当有用户输入的时候才返回数据
                String str = in.readLine();
                // 当用户连接断掉时会返回空值 null
                if (str == null) {
                    // 退出循环
                    break;
                } else {
                    StringBuffer strh = new StringBuffer();
                    StringBuffer strb = new StringBuffer();

                    HashMap<String, String> mapHead = dissolvePkgHeadStr(str);
                    for (String key : mapHead.keySet()) {
                        strh.append(key);
                        strh.append("=");
                        strh.append(mapHead.get(key));
                    }
                    HashMap<String, String> mapBody = dissolveRspPkgBodyStr(str);
                    for (String key : mapBody.keySet()) {
                        strb.append(key);
                        strb.append("=");
                        strb.append(mapBody.get(key));
                    }
                    String str1 = strh.toString();
                    String str2 = strb.toString();
                    // 对用户输入字串加前缀 Echo:,将此信息打印到客户端
                    out.println("Echo: " + str);
                    System.out.println("收到信息:"+str);
                    //打印包头
                    for (String keyHead : mapHead.keySet()) {
                        System.out.println(keyHead+"="+mapHead.get(keyHead));
                        out.println(keyHead+"="+mapHead.get(keyHead));
                    }
                    //打印包体
                    for (String keyBody : mapBody.keySet()) {
                        System.out.println(keyBody+"="+mapBody.get(keyBody));
                        out.println(keyBody+"="+mapBody.get(keyBody));
                    }
                    out.println(str1);
                    out.println(str2);
                    out.flush();
                }
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

public static void main(String[] args) throws IOException {
    Thread thread = new SocketAPIServer();
    thread.setDaemon(true);
    thread.start();
    while (true) {
        try {
            Thread.sleep(1000);
        } catch (Exception e) {
            e.printStackTrace();
            return;
        }
    }
}

}

[/code]

client
[code="java"]
package Work;

import java.io.*;
import java.net.*;
import java.util.HashMap;

// 客户端程序
public class SocketAPIClient {
/**
* 输入报文头
*
* @return str 报文头
*/
public static String inputPkgHead() throws IOException {
System.out.println("请输入报文长度");
String str1 = new BufferedReader(new InputStreamReader(System.in))
.readLine();

    System.out.println("请输入ID号");
    String str2 = new BufferedReader(new InputStreamReader(System.in))
            .readLine();

    System.out.println("请输入固定'0000'");
    String str3 = new BufferedReader(new InputStreamReader(System.in))
            .readLine();

    System.out.println("请输入交易码");
    String str4 = new BufferedReader(new InputStreamReader(System.in))
            .readLine();

    System.out.println("请输入客户经理号");
    String str5 = new BufferedReader(new InputStreamReader(System.in))
            .readLine();

    String str = str1 + "," + str2 + "," + str3 + "," + str4 + "," + str5;

    return str;
}

/**
 * 追加一定数目的空格到字符传尾,使其符合特定的长度
 * 
 * @param s
 *            原始字段
 * @param len
 *            定义长度
 * @return
 */
private static String tailPad2Str(String s, int len) {
    int length = 0;

    if (s == null) {
        s = "";
    }

    try {
        length = s.getBytes("gb18030").length;
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }
    if (length > len) {
        throw new IllegalArgumentException("STRING TOO LONG ...");
    }

    StringBuffer buffer = new StringBuffer();
    buffer.append(s);
    for (int i = 0; i < (len - length); i++) {
        buffer.append(' ');
    }

    return buffer.toString();
}

/**
 * 根据 流水ID, 交易码 生成报文头
 * 
 * @param seqNo
 * @param tradeCode
 * @return
 * @throws IOException
 */
public static String composePkgHeadStr() throws IOException {

    StringBuffer buffer = new StringBuffer();
    String t = inputPkgHead();
    String[] s = t.split(",");

    buffer.append(tailPad2Str(s[0], 6)); // 0-5_报文长度
    buffer.append(tailPad2Str(s[1], 6)); // 6-11_ID号
    buffer.append(tailPad2Str(s[2], 4)); // 12-15_固定"0000"
    buffer.append(tailPad2Str(s[3], 10)); // 16-25_六个字符串的交易码
    buffer.append(tailPad2Str(s[4], 8)); // 26-33_客户经理号
    buffer.append(tailPad2Str("", 21)); // 34-54_空格
    buffer.append(tailPad2Str("", 10)); // 55-64空格

    return buffer.toString();
}

/**
 * 生成报文体字符串
 * 
 * @param kcoll
 * @return
 * @throws IOException
 */
public static String composePkgBodyStr() throws IOException {

    StringBuffer buffer = new StringBuffer();
    HashMap<String, String> map = new HashMap<String, String>();
    // 输入报文体
    while (true) {
        System.out.println("请输入Key");
        String str1 = new BufferedReader(new InputStreamReader(System.in))
                .readLine();
        System.out.println("请输入Value");
        String str2 = new BufferedReader(new InputStreamReader(System.in))
                .readLine();
        map.put(str1, str2);
        System.out.println("输入'ENTER'提交或回车继续输入");
        String str3 = new BufferedReader(new InputStreamReader(System.in))
                .readLine();
        // 退出命令,equalsIgnoreCase() 是不区分大小写的比较
        if (str3.trim().equalsIgnoreCase("ENTER"))
            break;
    }

    if (map == null || map.size() == 0) {
        throw new IllegalArgumentException("PKG BODY IS EMPTY ..");
    } else {
        for (String key : map.keySet()) {
            buffer.append(key);
            buffer.append("=");
            buffer.append(map.get(key));
            buffer.append("|");
        }
    }

    return buffer.toString();
}

public static void main(String[] args) throws IOException

{
    Socket echoSocket = null;
    PrintWriter out = null;
    BufferedReader in = null;
    try {
        echoSocket = new Socket("localhost", 8888);
        out = new PrintWriter(echoSocket.getOutputStream(), true);
        in = new BufferedReader(new InputStreamReader(echoSocket
                .getInputStream()));
    } catch (UnknownHostException e) {
        System.err.println("Don't know about host: localhost.");
        System.exit(1);
    }
    System.out.println(in.readLine());
    String userInput = composePkgHeadStr() + composePkgBodyStr();
    // 将客户端 Socket 输入流(既服务器端 Socket 的输出流)输出到标准输出上
    out.println(userInput);
    System.out.println(in.readLine());
    System.out.println(in.readLine());
    System.out.println(in.readLine());
    System.out.println(in.readLine());
    out.close();
    in.close();
    System.out.println("输入'CLOSE'断开连接");
    String strClose = new BufferedReader(new InputStreamReader(System.in))
            .readLine();
    // 退出命令,equalsIgnoreCase() 是不区分大小写的比较
    if (strClose.trim().equalsIgnoreCase("CLOSE"))
        echoSocket.close();
}

}
[/code]

  • 写回答

1条回答 默认 最新

  • yuebancanghai 2012-08-09 13:39
    关注

    服务端在没有得到客户端响应而客户段突然关掉时,服务端同样会报错,因为服务端也在等待客户端响应

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 数值计算离散正交多项式
  • ¥30 数值计算均差系数编程
  • ¥15 redis-full-check比较 两个集群的数据出错
  • ¥15 Matlab编程问题
  • ¥15 训练的多模态特征融合模型准确度很低怎么办
  • ¥15 kylin启动报错log4j类冲突
  • ¥15 超声波模块测距控制点灯,灯的闪烁很不稳定,经过调试发现测的距离偏大
  • ¥15 import arcpy出现importing _arcgisscripting 找不到相关程序
  • ¥15 onvif+openssl,vs2022编译openssl64
  • ¥15 iOS 自定义输入法-第三方输入法