请教如何判断SOCKET长连接通信中,一段时间内是否收到对方的信息.及相关问题.

[复制链接]
查看11 | 回复4 | 2007-1-24 12:56:49 | 显示全部楼层 |阅读模式
对方的接口文档中要求:
1.2业务接口
服务端地址:211.151.234.131端口号:9007
Tcp协议适合发送量大,发送和接收比较及时,对于Tcp客户端由于某些原因一段时间内不能连接到分发中心服务器,所有的发向该客户端的MO短信和报告都会被缓存起来,等该客户端一旦连接,便会很快补发。
建议合作方建立一个发送一个接收2个连接,如果业务量很大,可以申请多于2个的连接,但须向业务申请后方可加连接,系统对于连接数是有限制的,每个合作方没有特殊声明时连接数是3,一般可以建2个连接,一个连接用于缓冲在某些情况下断开不能很好识别的情况。还有,对于每条连接,我们目前的速度限制是10条/秒,如果你的业务超过每连接每秒10条的限制,可以向业务申请调高每条连接的最高限速。
服务器端要求每连接每分钟都要能从客户端接收到至少一条指令数据,如果超过一分钟没有收到,服务器会向客户端发送一个测试指令,只要合作方回应该指令,那么就认为连接是处于激活状态,如果3分钟内服务端都无法接收到客户端的测试回应,将主动断开连接。客户端程序也应该设置3分钟内不能收到服务器端任何指令将主动断开连接并重新连接。为了防止分发中心连接负载太重,我们要求任何一个连接因任何原因在断开后20秒内不得连接,20秒后再尝试连接,否则如果在1分钟内超过我们设定的连接次数,我们将限制其在后续10分钟之内不能连接,并向系统管理员告警,由系统管理员根据情况停止该用户的合作帐户。
1.2.1连接登陆指令
连接登陆指令是在客户端成功连接后首先应当而且只能在此时发送的指令:
格式:
Login Name=【注册名】&Pwd=【注册密码】&Type=【注册类型,0:接收和发送;1:接收;2:发送;默认为0】(回车换行)
如果所有服务注册成功,服务器返回给客户端字符串:
Pass(回车换行)
否则将断开连接。对于一次未连接成功,应至少在20秒以后再重试连接,禁止连续的重试连接。

请问红色的话,我应该如何设置三分钟内不收到服务器任何指令将主动断开连接并重新连接.
我写的主要的客户端的代码:
父类线程:
public class ParentThread extends Thread {
private Socket socket;
protected BufferedReader reader;
protected BufferedWriter writer;

protected boolean isConnection=false;

protected boolean login(int type){

LoginRequest login = new LoginRequest(type);

//login.setRegType(type);

login.create();

try {

writer.write(login.getOrder());

writer.flush();

String str_order = reader.readLine();
System.out.println(str_order);
//
PassResponse pass = new PassResponse(str_order);
//
if(pass.isPass()){

if("Pass".equals(str_order)){

return true;

}else{

return false;

}

} catch (IOException e) {

e.printStackTrace();

}

return false;
}

protected void init(){

try {

socket = new Socket(Const.distributeCenterIP,Const.distributeCenterPort);

//socket.setSoTimeout(50000);



reader =new BufferedReader(new InputStreamReader(socket.getInputStream()));

writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));



isConnection=true;



} catch (UnknownHostException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}
}

protected void closeSocket(){

isConnection=false;

try {

if(reader != null)reader.close();

} catch (IOException e) {

e.printStackTrace();

}



try {

if(writer != null)writer.close();

} catch (IOException e) {

e.printStackTrace();

}



try {

if(socket != null)socket.close();

} catch (IOException e) {

e.printStackTrace();

}
}
}
接收短信连接,继承父类线程

public class SmsReceiver extends ParentThread {
private boolean toReconnection=false;
@Override
public void run() {

// TODO Auto-generated method stub

try{

init();

//登陆

boolean b = login(Const.reg_type_receive);

if(!b){//登陆失败,退出

SmsMain.log.error("登陆失败,程序退出!请检查注册名和口令是否正确&quot

;

SmsMain.log.info("注册名名:"+Const.reg_name);

SmsMain.log.info("用户口令:"+Const.reg_pwd);

SmsMain.log.info("注册类型:"+Const.reg_type_receive);

}

}catch(Exception e){

toReconnection = true;

}

while(true){



if(toReconnection){

/**20秒连接一次*/

try {

sleep(20000);

init();

//登陆

boolean b = login(Const.reg_type_receive);

toReconnection=false;

if(!b){//登陆失败,退出

SmsMain.log.error("登陆失败,程序退出!请检查注册名和口令是否正确&quot

;

SmsMain.log.info("注册名名:"+Const.reg_name);

SmsMain.log.info("用户口令:"+Const.reg_pwd);

SmsMain.log.info("注册类型:"+Const.reg_type_receive);

break;

}

} catch (InterruptedException e) {

e.printStackTrace();

}

}

if(!isConnection){//连接失败

toReconnection = true;

continue;

}



try {

String str_order = reader.readLine();
System.out.println(str_order);

Order order = new Order(str_order);

//如果为测试指令,发送回应

//if(order.isTestOrder()){

if("test".equals(str_order)){
System.out.println("---测试----&quot

;

writer.write(order.testOrder);

writer.flush();

toReconnection = false;

continue;

}



//处理



SMSBusinessCenter sbc = new SMSBusinessCenter(order);

Properties prop=sbc.performTask();

//发送回应
System.out.println(prop.getProperty("CommandId&quot

);

received(prop.getProperty("CommandId&quot

);



} catch (IOException e) {

e.printStackTrace();

}

}
}

private void received(String cid){

//Received received = new Received(Utils.getCurrentCommandId());
//
Received received = new Received(cid);
//
received.create();

try {

writer.write("Received CommandId="+cid+"\r\n&quot

;

writer.flush();

} catch (IOException e) {

e.printStackTrace();

}


}


}

发送短信连接,继承父类线程:
public class SmsSend extends ParentThread {
private boolean toReconnection=false;
@Override
public void run() {

try{

init();

//登陆

boolean b = login(Const.reg_type_send);

if(!b){//登陆失败,退出

SmsMain.log.error("登陆失败,程序退出!请检查注册名和口令是否正确&quot

;

SmsMain.log.info("注册名名:"+Const.reg_name);

SmsMain.log.info("用户口令:"+Const.reg_pwd);

SmsMain.log.info("注册类型:"+Const.reg_type_send);

}

}catch(Exception e){

toReconnection = true;

}

while(true){



if(toReconnection){

/**20秒连接一次*/

try {

sleep(20000);

init();

//登陆

boolean b = login(Const.reg_type_send);

toReconnection=false;

if(!b){//登陆失败,退出

SmsMain.log.error("登陆失败,程序退出!请检查注册名和口令是否正确&quot

;

SmsMain.log.info("注册名名:"+Const.reg_name);

SmsMain.log.info("用户口令:"+Const.reg_pwd);

SmsMain.log.info("注册类型:"+Const.reg_type_send);

break;

}

} catch (InterruptedException e) {

e.printStackTrace();

}

}

if(!isConnection){//连接失败

toReconnection = true;

continue;

}



try {

String str_order = reader.readLine();

Order order = new Order(str_order);

//如果为测试指令,发送回应

if(order.isTestOrder()){

writer.write(order.testOrder);

toReconnection = false;

//continue;

}


//
//处理
//
SMSBusinessCenter sbc = new SMSBusinessCenter(order);
//
Vector msgs = sbc.getSendMsg();
//
//发送短信
//
//for(){
//
writer.write("&quot

;
//

//


//发送短信



if(SmsMain.list!=null&&SmsMain.list.size()>0){

synchronized (SmsMain.list) {

for (Iterator iterator = SmsMain.list.iterator(); iterator

.hasNext()

{

SubmitRequest sr = (SubmitRequest) iterator.next();

StringBuffer sb = new StringBuffer();

sb.append(Const.order_submit+" ")

.append("CommandId="+sr.getCommandId())

.append("&GateWay="+sr.getGateWay())

.append("&GateName="+sr.getGateName())

.append("&ItemId="+sr.getItemId())

.append("&SpNumber="+sr.getSpNumber())

.append("&UserNumber:="+bin2hex(sr.getUserNumber()))

.append("&UserNumberType="+sr.getUserNumberType())

.append("&FeeNumber="+sr.getFeeNumber())

.append("&FeeNumberType="+sr.getFeeNumberType())

.append("&FeeType="+sr.getFeeType())

.append("&ScheduleTime="+sr.getScheduleTime())

.append("&ExpireTime="+sr.getExpireTime())

.append("&MtFlag="+sr.getMtFlag())

.append("&ReportFlag="+sr.getReportFlag())

.append("&MsgCode="+sr.getMsgCode())

.append("&MsgId="+sr.getMsgId())

.append("&ExtData:="+sr.getExtData())

.append("&TP_pId="+sr.getTp_pId())

.append("&TP_udhi="+sr.getTp_udhi())

.append("&Msg:="+bin2hex(sr.getMsg()))

.append("&LinkID="+sr.getLinkID())

.append("&ItemType="+sr.getItemType()+"\r\n");

writer.write(sb.toString());

writer.flush();

SmsMain.list.remove(sr);

}

}

//接受回应

received();

}





} catch (IOException e) {

e.printStackTrace();

}

}
}

private void received(){



try {

String line = reader.readLine();
//
Received received = new Received(line);
//
received.parse();
System.out.println(line);
SmsMain.log.info(line);

} catch (IOException e) {

e.printStackTrace();

}


}
/**
* 字符串转换成十六进制值
* @param bin String 转换成十六进制的字符串
* @return
*/
public static String bin2hex(String bin) {
char[] digital = "0123456789ABCDEF".toCharArray();
StringBuffer sb = new StringBuffer("");
byte[] bs = bin.getBytes();
int bit;
for (int i = 0; i > 4;

sb.append(digital[bit]);

bit = bs & 0x0f;

sb.append(digital[bit]);
}
return sb.toString();
}

}

回复

使用道具 举报

千问 | 2007-1-24 12:56:49 | 显示全部楼层
想问什么问题? 贴这些代码说明什么?
回复

使用道具 举报

千问 | 2007-1-24 12:56:49 | 显示全部楼层
//socket.setSoTimeout(50000);
timeout不就的了
回复

使用道具 举报

千问 | 2007-1-24 12:56:49 | 显示全部楼层
timeout
对存放接收消息的堆栈检查
对ping对方接收响应的时点进行检查
回复

使用道具 举报

千问 | 2007-1-24 12:56:49 | 显示全部楼层
好比socket.timeout(30000)
我如何判断在这三十秒钟我的SOCKET是否接到消息?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题

0

回帖

4882万

积分

论坛元老

Rank: 8Rank: 8

积分
48824836
热门排行