这是一个socket长连接的程序,代码如下。我是在windows命令窗口运行socket服务器的。如果有机器设备通过我规定好的代码请求服务器,我就给设备建立长连接进行通讯。然后如果有另外的客户端通过规定好的代码请求,我就发送指令给指定设备,然后设备返回信息,再返回给客户端,这种是短连接。但是很奇怪的就是,总有应该是网络的爬虫请求我的程序,总收到一些乱七八糟的字符串,但是因为这些字符串和我规定的不一样,所以是拦截在外面的,建立不了长连接。最麻烦的来了,当程序运行久了以后或者一定时间,我客户端请求服务器短连接就超时了,服务器命令窗口没显示信息,但是如果我ctrl+c结束一下,请求的字符串又能打印出来了了,好像整个程序挂起来没反应,以至于程序很不稳定,设备用久了总是要重启服务器程序才能恢复。新手socket,不知道是否有精通的大神,能解答一下。会不会是接收数据那段出现了问题呢,代码如下:
class SocketThread implements Runnable {
private Socket socket;
public SocketThread(Socket socket) {
this.socket = socket;
}
public void run() {
InputStreamReader isr = null;
BufferedReader br = null;
OutputStreamWriter osr = null;
BufferedWriter bw = null;
try {
isr = new InputStreamReader(socket.getInputStream());
br = new BufferedReader(isr);
osr = new OutputStreamWriter(socket.getOutputStream());
bw = new BufferedWriter(osr);
char[] chars = new char[1024];
int len;
String resultMsg = "";
while((len = br.read(chars)) != -1){
if (1024 == len) {
resultMsg += chars;
}
else {
for (int i = 0; i < len; i++) {
resultMsg += chars[i];
}
resultMsg = resultMsg.trim();
System.out.println("data:"+resultMsg);
/**
* 新设备连接
*/
if(resultMsg.indexOf("LSKJ:")!=-1){
// 下面这个方法是保存socket到map中
ConnectNew(resultMsg, socket, bw);
}
/**
* 发送代码
*/
if(resultMsg.indexOf("<CODE>")!=-1){
// 普通客户端连接
int tradeCode = Integer.parseInt(SocketUtil.getXMLData(resultMsg, "CODE"));
switch (tradeCode) {
case 100:// 100代码:往设备电路板发送指令
String command = SocketUtil.getXMLData(resultMsg, "COMMAND");
String deviceIp = SocketUtil.getXMLData(resultMsg, "IP");// IP地址
int devicePort = Integer.parseInt(SocketUtil.getXMLData(resultMsg, "PORT")); // 端口
Socket sourceSocket = socketMap.get(devicePort);
clientMap.put(socket.getPort(), socket);
Writer targetWriter = new OutputStreamWriter(sourceSocket.getOutputStream());
targetWriter.write(command+":LSYD:"+socket.getPort());
targetWriter.flush();
break;
case 101:// 101代码:查询socket的数据
StringBuffer returnMsg = new StringBuffer();
if(!socketMap.isEmpty()){
for (Socket socket:socketMap.values()) {
returnMsg.append(socket.getInetAddress().getHostAddress()).append(":").append(socket.getPort());
returnMsg.append("\n");
}
}else{
returnMsg.append(" socketMap is null");
}
bw.write(returnMsg.toString());
bw.flush();
break;
default:
break;
}
}
/**
* 响应代码
*/
if(resultMsg.indexOf("LSYD:")!=-1){
/**
* 返回例子:
* OUDC1_??:LSYD:10001 OFF
*/
String[] msg = resultMsg.split(":");
if(msg.length>=2){
String returnCommand = resultMsg.split(":")[2];
if(returnCommand.length()>=4){
// 取出返回端口号
returnCommand = returnCommand.substring(0, 5);
String regEx="[^0-9]";
Pattern p = Pattern.compile(regEx);
Matcher m = p.matcher(returnCommand);
// 端口号
int clientPort = Integer.parseInt(m.replaceAll("").trim());
//System.out.println("端口号是:"+clientPort);
// 返回结果
String result = resultMsg.substring(resultMsg.lastIndexOf(" ")+1,resultMsg.length());
//取出socket返回
Socket clientSocket = clientMap.get(clientPort);
if(clientSocket!=null){
Writer targetWriter = new OutputStreamWriter(clientSocket.getOutputStream());
targetWriter.write(result);
targetWriter.flush();
clientMap.remove(clientPort);
}
}
}
}
}
resultMsg ="";
}
} catch (IOException e) {
e.printStackTrace();
} finally {
}
}
}
代码解释一下,当有LSKJ:00001请求的话,服务器就建立长连接,同时保存了IP和端口了,然后如果有<CODE>100</CODE><COMMAND>OUDC1_??</COMMAND><IP>192.168.1.222</IP><PORT>55775</PORT>这种信息请求的话,我就知道是要发送给指定的设备,然后等待设备返回指令OUDC1_ON=030:LSYD:54498:OK,我就知道要返回给54498端口的客户端短连接数据了。
java socket 无故当机
- 写回答
- 好问题 0 提建议
- 追加酬金
- 关注问题
- 邀请回答
-
3条回答
- 银河曼巴 2018-07-16 04:28关注
TCP Socket连接是双向的,通过四次挥手的方式断开,双方分别调用Socket.close()方法断开连接。连接断开的过程中,一般一方A先断开连接,另一方B发现A断开连接后,也断开连接。为方便表述,将先断开连接的一方A称为“主动断开连接”;后断开的一方B,则为“被动断开连接”。
在一方B阻塞执行in.readUTF()方法时,如果对方A主动断开Socket连接,这个方法会抛出异常。从而在B处理异常时,可以被动的断开这边的连接。
为保证主动断开连接的一方不会阻塞在in.readUTF()方法中,需要先执行socket.shutdownInput()。所以主动断开连接的代码如下。
socket.shutdownInput();
in.close();
socket.close();被动断开连接的一方,在捕获到in.readUTF()的异常后,断开Socket连接。
复制代码
try {
String s = in.readUTF();
} catch (IOException e) {
// 连接被断开(被动)
try {
in.close();
socket.close();
in = null;
socket = null;
} catch (IOException e) {
e.printStackTrace();
}
}解决 无用评论 打赏 举报
悬赏问题
- ¥15 ads仿真结果在圆图上是怎么读数的
- ¥20 Cotex M3的调试和程序执行方式是什么样的?
- ¥20 java项目连接sqlserver时报ssl相关错误
- ¥15 一道python难题3
- ¥15 用matlab 设计一个不动点迭代法求解非线性方程组的代码
- ¥15 牛顿斯科特系数表表示
- ¥15 arduino 步进电机
- ¥20 程序进入HardFault_Handler
- ¥15 oracle集群安装出bug
- ¥15 关于#python#的问题:自动化测试