0 0

socket connection resect5

我写了一个传送报文的socket,正常情况下服务器端和客户端都没有问题,但是只要客户端在报错,服务器端就会报connection reset,理论上客户端的操作应该对服务器端没有影响才对啊
server
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<String, String> dissolveRspPkgBodyStr(String rspPkgStr)
			throws Exception {
		HashMap<String, String> hashMap = new HashMap<String, String>();

		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;
			}
		}
	}
}



client
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();
	}
}
2012年7月25日 20:45

1个答案 按时间排序 按投票排序

0 0

采纳的答案

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

2012年8月09日 13:39

相关推荐

Global site tag (gtag.js) - Google Analytics