我写了一个传送报文的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]