我写了一个传送报文的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();
}
}
相关推荐
基于springboot大学生就业信息管理系统源码数据库文档.zip
基于java的驾校收支管理可视化平台的开题报告
时间序列 原木 间隔5秒钟 20241120
毕业设计&课设_基于 Vue 的电影在线预订与管理系统:后台 Java(SSM)代码,为毕业设计项目.zip
基于springboot课件通中小学教学课件共享平台源码数据库文档.zip
基于java的网上购物商城的开题报告
Delphi人脸检测与识别Demo1fdef-main.zip
基于java的咖啡在线销售系统的开题报告
基于java的自助医疗服务系统的开题报告.docx
内容概要:本文档全面介绍了Visual Basic(VB)编程语言的基础知识和高级应用。首先概述了VB的基本特性和开发环境,随后详细讲述了VB的数据类型、变量、运算符、控制结构、数组、过程与函数、变量作用域等内容。接着介绍了窗体设计、控件使用、菜单与工具栏的设计,文件操作、数据库访问等关键知识点。最后讨论了VB的学习方法、发展历史及其在桌面应用、Web应用、数据库应用、游戏开发和自动化脚本编写等领域的广泛应用前景。 适合人群:初学者和中级程序员,尤其是希望快速掌握Windows桌面应用开发的人群。 使用场景及目标:①掌握VB的基础语法和开发环境;②学会使用VB创建复杂的用户界面和功能完整的应用程序;③理解数据库操作、文件管理和网络编程等高级主题。 其他说明:Visual Basic是一种简单易学且功能强大的编程语言,尤其适合用于开发Windows桌面应用。文中不仅覆盖了基础知识,还包括了大量的实用案例和技术细节,帮助读者快速提升编程技能。
基于java的疫情期间高校防控系统开题报告.docx
基于springboot+vue社区老年人帮扶系统源码数据库文档.zip
基于java的超市商品管理系统的开题报告.docx
基于SpringBoot房屋买卖平台源码数据库文档.zip
xdu限通院23微处理器系统与应用大作业(两只老虎),适应于汇编语言keil软件,
<项目介绍> - 新闻类网站系统,基于SSM(Spring、Spring MVC、MyBatis)+MySQL开发,高分成品毕业设计,附带往届论文 - 不懂运行,下载完可以私聊问,可远程教学 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 --------
基于java的学生网上请假系统的开题报告.docx
社会经济繁荣发展的今天,电子商务得到了飞速发展,网上交易越来越彰显出其独特的优越性,在人们的日常生活中,出现了各种类型的交易网站。其中一个就是车辆易主交易网站,它是一个服务于用户买卖二手车辆的交易网站,为用户提供了平等互利、方便快捷的网上交易平台,通过这一类型的网站,用户可自由出售和购买车辆。 本课题主要根据车辆本身的特性,充分发挥互联网的特点与优势,构建一个以二手车辆为商品、基于互联网平台的车辆易主业务交易管理系统,并根据车辆易主业务交易管理系统的应用需求,进行需求分析,进而对网站系统作规划设计。采用IDEA为运行平台,以SSH为框架,运用HTML语言、JSP技术、MySql数据库、JSP与后台数据库链接等关键技术建设二手车网上交易系统,构建车辆易主交易系统的会员注册与登录,网站首页展示、用户发布商品车辆,用户求购商品车辆,分页浏览、购物系统、用户后台管理、管理员用户后台管理等功能,并使这些功能得以实现并更好为用户服务。网站整体构建完成且测试成功后,用户可以进入网站进行注册、登录,登录后,用户可以在网站上发布自己的闲置车辆或者寻找想要购买的车辆,还可以收藏车辆,管理发布和收藏的车辆,
SQLite3的向量扩展库,windows dll,版本0.1.5
基于C++实现(控制台)商品库存管理系统