服务端采用JAVA编写,客户端是C,都是运行在同一台机器上,OS是LINUX
如果客户端第一次发送的数据很大,那么就会出现connection reset这个异常
可是如果第一次发送比较少,那么不会出现这个异常一旦出现这个异常,那么客户端再次发送的数据,就不能接收到了服务端:
我启动了两个线程,
一个是专门用于监听接收客户端的数据,
另外一个是专门用于处理接收到的数据,监听接收到的数据的线程代码如下:
public class ThreadRcvMsg
{
public static boolean bExitThread = false; // 退出线程标志 static ServerSocket servsock;
public static final int QUIT_SLEEP_TIME = 5000; public ThreadRcvMsg()
{
try
{
servsock = new ServerSocket(GlobalData.serviceAlarmPort);
/*设置端口重用,当上次绑定失败后,下次绑定仍能成功*/
servsock.setReuseAddress(true);
}
catch (IOException e)
{
WebuiLog.writeDebugLog("Can not create ServerSocket:"
+ e.toString());
return;
}
// 创建线程,并启动它们
new Handler(servsock).start();
}
public static CommonResult quitThreadRcvMsg()
{
bExitThread = true; //退出标记为TRUE
// 发送消息给自己,退出告警接收线程
String exitMsg = "Begin to exit.";
byte[] data = exitMsg.getBytes();
SocketClient socket = null;
socket = new SocketClient(GlobalData.localInnerIpAddr,
GlobalData.serviceAlarmPort);
if (null == socket)
{
WebuiLog.writeDebugLog("Send exit message error");
return null;
}
// send msg
CommonResult sendResult = socket.sendNotRev(data);
try
{
Thread.sleep(QUIT_SLEEP_TIME);
}
catch (Exception e)
{
WebuiLog.writeDebugLog("Sleep error:"
+ e.getLocalizedMessage());
}
return sendResult;
}
}
class Handler extends Thread
{
final static int RCV_LEN = 284; // 每次接受数据的长度7个int ServerSocket servsock;
Handler(ServerSocket socket)
{
super();
servsock = socket;
} MgmtMsg dataFlowIntoMsg(byte[] into)
{
return new MgmtMsg(into);
} public void run()
{
int j = 0;
byte[] data = new byte[RCV_LEN];
// 等待一个连接
while (true)
{
Socket clientsocket = null;
try
{
if (ThreadRcvMsg.bExitThread)
{
if (!servsock.isClosed())
{
servsock.close();
}
WebuiLog.writeDebugLog("Alarm thread exit in loop.");
break; // 退出线程
}
// 等待下一个连接
if (servsock.isClosed())
{
break;
}
//clientsocket.setReuseAddress(true);
clientsocket = servsock.accept();
BufferedInputStream in = new BufferedInputStream(clientsocket
.getInputStream());
while(in.read(data) > 0)
{
// //收到退出消息
if (true == ThreadRcvMsg.bExitThread)
{
if (null != servsock)
{
servsock.close();
}
break;
}
synchronized (GlobalData.alarmMgmtMutex)
{
GlobalData.alarmList.add(this.dataFlowIntoMsg(data));
j++;
WebuiLog.writeDebugLog("send alarm j is : " + j);
}
}
}
catch (IOException all)
{
WebuiLog.writeDebugLog("Thread handle error:"
+ all.toString());
}
finally
{
try
{
clientsocket.close();
}
catch(IOException e)
{
WebuiLog.writeDebugLog("Close alarm socket error:" + e.toString());
}
}
}
}
}处理接收到的数据的线程如下:
public class AlarmThread implements Runnable
{
private static boolean bExitThread = false; // 退出线程标志
public static int i = 0;
public AlarmThread()
{
}
MgmtMsg dataFlowIntoMsg(byte[] into)
{
return new MgmtMsg(into);
}
public void run()
{
MgmtMsg data = null;
while(!ThreadRcvMsg.bExitThread)
{
synchronized (GlobalData.alarmMgmtMutex)
{
data = null;
if (ThreadRcvMsg.bExitThread)
{
break;
解决方案 »
- 求助获取鼠标在屏幕进行点击的位置的坐标,及获取在屏幕的拖拽事件。注:不是用组件注册,而是屏幕。
- 如何将.NET三层结构中的增、删、改操作用一个方法封装呢?
- 请问怎么把java中的撤消功能实现在菜单项中呢,!!菜单项有快捷键
- 递归方法打印数字塔
- 研究生专业方向 大家帮我选一下
- 请问关于Applet的显示问题,头疼。
- java最终的文件格式是什么啊???
- 如何显示子目录内的文件列表?各位高手指点哈~
- classpath的问题
- Developer studio什么意思?create new class 什么意思?
- 请问:ojdbc14.jar的驱动可不可以用于JDK1.5下的Oracle访问?有没有更好的驱动
- 获得hashtable的key
网络处理也要修改一下首先没有看到你的报文头处理部分。你怎么知道一个数据报有多大呢?只是无畏的在那里read,可是每一个报文的起点和终结点怎么知道
还有,你用来接收的data长度是固定的,而数据长度是可变的,怎么进行数据合并呢?我没仔细看,不过感觉你是把收到的数据直接进行处理,也就是说read一次就把数据交给处理方法处理,却不关心数据是不是都收到了。而且每次收到数据并交付处理后data也不清空,如果第一次收到了100个数据,第二次收到了50个,但你的data里面其实前100位都不为0,你的处理方法怎么知道这是哪次收到的数据呢。
他们是加锁处理的啊
所以,不是你说的接受到数据,就立即进行处理的data,我是从socket里面读取的,如果这次socket关闭了之后,那么data就没有了吧
需要清空么?
该如何清空呢?谢谢
while(in.read(data) > 0)
{
// //收到退出消息
if (true == ThreadRcvMsg.bExitThread)
{
if (null != servsock)
{
servsock.close();
}
break;
}
synchronized (GlobalData.alarmMgmtMutex)
{
GlobalData.alarmList.add(this.dataFlowIntoMsg(data));
j++;
WebuiLog.writeDebugLog("send alarm j is : " + j);
}
}在
while(in.read(data) > 0)
的时候读取数据,读到后交给
dataFlowIntoMsg(data)处理
如果一次读取完毕应该没有问题,但如果一次没有读完呢?
假设data=new byte[1024];
第一次读取了1024个byte,之后再读第二次。假设读取了64个字节,你还是调用dataFlowIntoMsg(data)处理,那么你怎么知道第二次只有64个字节呢?或者说你怎么知道整个数据包一共只有1024+64个字节而不是1024+1024个呢?另外,我仔细看了一下你的代码,dataFlowIntoMsg()方法其实是返回一个类,传入的参数变成MgmtMsg实力放到队列准备处理。我不知道你的MgmtMsg是怎么做的,如果只是将data作为一个变量储存,那非常可怕。你队列里所有MgmtMsg节点的data变量实际上指向的都是同一个实例,第二次读取的时候就会改变以前放到队列中的数据。(只是猜测)当然这些不一定就是问题所在,不过确实是一个很严重的问题。建议你在调用dataFlowIntoMsg(data)后重新data=new byte[REC_LEN]一下,给他一个新的对象。
如果是实验,建议还是在不同的机器上进行更贴近实际情况。
如果不是实验,用SOCKET通信似乎太绕了点。
是同一台机器上的啊
数据是一次最多284个字节
这个是客户端和服务端确定好了的
难道
synchronized (GlobalData.alarmMgmtMutex)
{
GlobalData.alarmList.add(this.dataFlowIntoMsg(data));
j++;
WebuiLog.writeDebugLog("send alarm j is : " + j);
}
这里,我用GlobalData.alarmList.add(this.dataFlowIntoMsg(data));
这个有错么?