4

我正在尝试使用 JAVA 发送短信。谷歌搜索后,我发现要使用 SMPP 协议并偶然发现以下源代码。

public class SendSMS
{
public static void main(String[] args) throws Exception
{
    SendSMS obj = new SendSMS();
    SendSMS.sendTextMessage("<mobile number>");
}

private TimeFormatter tF = new AbsoluteTimeFormatter();

/*
 * This method is used to send SMS to for the given MSISDN
 */
public void sendTextMessage(String MSISDN)
{

    // bind param instance is created with parameters for binding with SMSC
    BindParameter bP = new BindParameter(
            BindType.BIND_TX, 
            "<user_name>",
            "<pass_word>", 
            "<SYSTEM_TYPE>", 
            TypeOfNumber.UNKNOWN,
            NumberingPlanIndicator.UNKNOWN,
            null);

    SMPPSession smppSession = null;

    try
    {
        // smpp session is created using the bindparam and the smsc ip address/port
        smppSession = new SMPPSession("<SMSC_IP_ADDRESS>", 7777, bP);
    }
    catch (IOException e1)
    {
        e1.printStackTrace();
    }

    // Sample TextMessage
    String message = "This is a Test Message";

    GeneralDataCoding dataCoding = new GeneralDataCoding(false, true,
            MessageClass.CLASS1, Alphabet.ALPHA_DEFAULT);

    ESMClass esmClass = new ESMClass();

    try
    {
        // submitShortMessage(..) method is parametrized with necessary
        // elements of SMPP submit_sm PDU to send a short message
        // the message length for short message is 140
        smppSession.submitShortMessage(
                "CMT",
                TypeOfNumber.NATIONAL,
                NumberingPlanIndicator.ISDN,
                "<MSISDN>",
                TypeOfNumber.NATIONAL, 
                NumberingPlanIndicator.ISDN, 
                MSISDN,
                esmClass, 
                (byte) 0, 
                (byte) 0, 
                tF.format(new Date()),
                null,
                new RegisteredDelivery(SMSCDeliveryReceipt.DEFAULT),
                (byte) 0,
                dataCoding, 
                (byte) 0, 
                message.getBytes());
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }
}

}

但是我在源代码中遇到的问题是它需要一组特定的参数,如用户名、密码、系统类型、SMSC IP 地址等,我不知道。我最近才知道 SMPP 协议,所以我不知道如何让这个代码工作来完成我向我的手机发送短信的用例。那么有人可以帮我让这个代码工作或指导我到一个我可以学习这样做的地方吗?

4

4 回答 4

6

我最近一直在从事 SMPP 项目。

我用于 SMPP 协议的库是OpenSMPP

这是我的类用于构建和发送 SMPP 数据的示例

public class SmppTransport implements Transport {

@Override
public void send(String url, Map<String, String> map) throws IOException {
    int smscPort = Integer.parseInt(map.get("port"));
    String smscHost = map.get("send_url");
    String smscUsername = map.get("username");
    String smscPassword = map.get("password");
    String recipientPhoneNumber = map.get("phone_num");
    String messageText = map.get("text");

    try {
        SubmitSM request = new SubmitSM();
     // request.setSourceAddr(createAddress(senderPhoneNumber)); // you can skip this
        request.setDestAddr(createAddress(recipientPhoneNumber));
        request.setShortMessage(messageText);
     // request.setScheduleDeliveryTime(deliveryTime);           // you can skip this
        request.setReplaceIfPresentFlag((byte) 0);
        request.setEsmClass((byte) 0);
        request.setProtocolId((byte) 0);
        request.setPriorityFlag((byte) 0);
        request.setRegisteredDelivery((byte) 1); // we want delivery reports
        request.setDataCoding((byte) 0);
        request.setSmDefaultMsgId((byte) 0);

        Session session = getSession(smscHost, smscPort, smscUsername, smscPassword);
        SubmitSMResp response = session.submit(request);
    } catch (Throwable e) {
        // error
    }
}

private Session getSession(String smscHost, int smscPort, String smscUsername, String smscPassword) throws Exception{
    if(sessionMap.containsKey(smscUsername)) {
        return sessionMap.get(smscUsername);
    }

    BindRequest request = new BindTransmitter();
    request.setSystemId(smscUsername);
    request.setPassword(smscPassword);
 // request.setSystemType(systemType);
 // request.setAddressRange(addressRange);
    request.setInterfaceVersion((byte) 0x34); // SMPP protocol version

    TCPIPConnection connection = new TCPIPConnection(smscHost, smscPort);
 // connection.setReceiveTimeout(BIND_TIMEOUT);
    Session session = new Session(connection);
    sessionMap.put(smscUsername, session);

    BindResponse response = session.bind(request);
    return session;
}

private Address createAddress(String address) throws WrongLengthOfStringException {
    Address addressInst = new Address();
    addressInst.setTon((byte) 5); // national ton
    addressInst.setNpi((byte) 0); // numeric plan indicator
    addressInst.setAddress(address, Data.SM_ADDR_LEN);
    return addressInst;
}

}

我的操作员给了我这个 SMPP 的参数。有许多配置选项,但这些是必不可少的

#host = 192.168.10.10 // operator smpp server ip
#port = 12345         // operator smpp server port
#smsc-username = "my_user" 
#smsc-password = "my_pass" 
#system-type = "" 
#source-addr-ton = 5
#source-addr-npi = 0

因此,如果您想在不注册 GSM 服务提供商的情况下测试您的代码,您可以在您的计算机上模拟 SMPP 服务器。SMPPSim是一个很棒的测试项目。下载它并在您的计算机上运行。它可以通过多种方式进行配置,例如从 SMPP 服务器请求交付报告、设置短信失败率等我已经在 linux 上测试了 SMPPSim。

于 2014-11-04T08:03:24.777 回答
2

使用以下代码执行单个类:

public class SmppTransport {

static Map sessionMap=new HashMap<String,String>(); 
String result=null;
public String send(String url, Map<String, String> map) throws Exception {
    int smscPort = Integer.parseInt(map.get("port"));
    String smscHost = map.get("send_url");
    String smscUsername = map.get("username");
    String smscPassword = map.get("password");
    String recipientPhoneNumber = map.get("phone_num");
    String messageText = map.get("text");

    try {
        SubmitSM request = new SubmitSM();
     // request.setSourceAddr(createAddress(senderPhoneNumber)); // you can skip this
        request.setDestAddr(createAddress(recipientPhoneNumber));
        request.setShortMessage(messageText);
     // request.setScheduleDeliveryTime(deliveryTime);           // you can skip this
        request.setReplaceIfPresentFlag((byte) 0);
        request.setEsmClass((byte) 0);
        request.setProtocolId((byte) 0);
        request.setPriorityFlag((byte) 0);
        request.setRegisteredDelivery((byte) 1); // we want delivery reports
        request.setDataCoding((byte) 0);
        request.setSmDefaultMsgId((byte) 0);

        Session session = getSession(smscHost, smscPort, smscUsername, smscPassword);
        SubmitSMResp response = session.submit(request);
        result=new String(response.toString());
    } catch (Exception e) {
        result=StackTraceToString(e);
    }
    return result;
}

private Session getSession(String smscHost, int smscPort, String smscUsername, String smscPassword) throws Exception{

    if(sessionMap.containsKey(smscUsername)) {
        return (Session) sessionMap.get(smscUsername);
    }

    BindRequest request = new BindTransmitter();
    request.setSystemId(smscUsername);
    request.setPassword(smscPassword);
    request.setSystemType("smpp");

 // request.setAddressRange(addressRange);
    request.setInterfaceVersion((byte) 0x34); // SMPP protocol version

    TCPIPConnection connection = new TCPIPConnection(smscHost, smscPort);
 // connection.setReceiveTimeout(BIND_TIMEOUT);
    Session session = new Session(connection);
    sessionMap.put(smscUsername, session.toString());

    BindResponse response = session.bind(request);
    return session;
}

private Address createAddress(String address) throws WrongLengthOfStringException {
    Address addressInst = new Address();
    addressInst.setTon((byte) 5); // national ton
    addressInst.setNpi((byte) 0); // numeric plan indicator
    addressInst.setAddress(address, Data.SM_ADDR_LEN);
    return addressInst;
}

public String StackTraceToString(Exception err) {
    StringWriter sw = new StringWriter();
    PrintWriter pw = new PrintWriter(sw);
    err.printStackTrace(pw);
    return sw.toString();
    }



public String sendSMS(String Port, String Host,String SMPPUserName,String SMPPPassword,String Phone_Number,String Message) throws Exception {
    String response=null;
    sessionMap.put("port",Port);
    sessionMap.put("send_url",Host);    
    sessionMap.put("username",SMPPUserName);
    sessionMap.put("password",SMPPPassword);
    sessionMap.put("phone_num",Phone_Number);
    sessionMap.put("text",Message);
    Set set=sessionMap.entrySet();//Converting to Set so that we can traverse  
    Iterator itr=set.iterator(); 
    while(itr.hasNext()){  

      Map.Entry entry=(Map.Entry)itr.next();  
           }  

    SmppTransport test =new SmppTransport();
    try {
        response=test.send("10.50.**.**", sessionMap);
        System.out.println(response);
    } catch (Exception e) {

        response=StackTraceToString(e);
    }
    return response;

}

public static void main(String[] args) throws Exception
{
    SmppTransport sm=new SmppTransport();
    String test=sm.sendSMS("80*6", "10.50.**.**", "f***obi", "x***fQ", "+9187965*****", "Testing1");
    System.out.println("Data: "+test);

}}
于 2019-11-20T10:48:55.440 回答
1

在此处使用此模拟器,它充当服务提供者,在其上构建和测试您的应用程序后,您只需更改服务提供者提供给您的配置参数(用户名、密码、ip、端口...)。

您可以在 conf 文件中找到连接到此模拟器的所有配置。

于 2014-11-04T08:06:14.217 回答
0

SMPP 是移动网络运营商/运营商和内容提供商之间的协议。您指定的字段(用户名、密码、SMSC IP)由运营商提供。不幸的是,除非您为内容提供商公司工作,或与运营商达成协议,否则您不太可能获得这些详细信息。

模拟器可以让您测试您的 SMPP 代码,但它们实际上不会将内容传送到您的手机。

如果您想从 Java 应用程序发送 SMS,我最好的建议是使用像Twilio 的SMS API 。

于 2014-11-04T08:14:41.633 回答