基于sip的java编程实例

网站上关于基于sip的java编程实例实在是太少了,这个严重影响了sip的传播和发展,所以我上传了这个小实验,让大家参考下。 

在做实验前,我们需要一些东西: 
我的环境: 
XP 
Eclipse 

需要包: 

这个需要在网上自己找,或者hi我,我也可以给你们哈。----百度账号:时光可见 

好了,现在看程序了哈,主要是三个文件。 

MessageProcessor.java : 
public interface MessageProcessor 

    public void processMessage(String sender, String message); 
    public void processError(String errorMessage); 
    public void processInfo(String infoMessage); 


SipLayer.java : 

import java.text.ParseException; 
import java.util.*; 
import javax.sip.*; 
import javax.sip.address.*; 
import javax.sip.header.*; 
import javax.sip.message.*; 

public class SipLayer implements SipListener { 

private MessageProcessor messageProcessor; 

private String username; 

private SipStack sipStack; 

private SipFactory sipFactory; 

private AddressFactory addressFactory; 

private HeaderFactory headerFactory; 

private MessageFactory messageFactory; 

private SipProvider sipProvider; 

/** Here we initialize the SIP stack. */ 
public SipLayer(String username, String ip, int port) 
throws PeerUnavailableException, TransportNotSupportedException, 
InvalidArgumentException, ObjectInUseException, 
TooManyListenersException { 

setUsername(username); 
sipFactory = SipFactory.getInstance(); 
sipFactory.setPathName("gov.nist"); 
Properties properties = new Properties(); 
properties.setProperty("javax.sip.STACK_NAME", "TextClient"); 
properties.setProperty("javax.sip.IP_ADDRESS", ip); 

// DEBUGGING: Information will go to files 
// textclient.log and textclientdebug.log 
properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "32"); 
properties.setProperty("gov.nist.javax.sip.SERVER_LOG", "textclient.txt"); 
properties.setProperty("gov.nist.javax.sip.DEBUG_LOG", "textclientdebug.log"); 

sipStack = sipFactory.createSipStack(properties); 
headerFactory = sipFactory.createHeaderFactory(); 
addressFactory = sipFactory.createAddressFactory(); 
messageFactory = sipFactory.createMessageFactory(); 

// ListeningPoint tcp = sipStack.createListeningPoint(port, "tcp"); 
ListeningPoint udp = sipStack.createListeningPoint(port, "udp"); 

// sipProvider = sipStack.createSipProvider(tcp); 
// sipProvider.addSipListener(this); 

// suppose UDP is used as transport, Bob Cheng, 03-11-10 
sipProvider = sipStack.createSipProvider(udp); 
sipProvider.addSipListener(this); 


/** 
* This method uses the SIP stack to send a message. 
*/ 
public void sendMessage(String to, String message) throws ParseException, 
InvalidArgumentException, SipException { 

SipURI from = addressFactory.createSipURI(getUsername(), getHost() + ":" + getPort()); 
Address fromNameAddress = addressFactory.createAddress(from); 
fromNameAddress.setDisplayName(getUsername()); 
FromHeader fromHeader = headerFactory.createFromHeader(fromNameAddress, "textclientv1.0"); 

String username = to.substring(to.indexOf(":") + 1, to.indexOf("@")); 
String address = to.substring(to.indexOf("@") + 1); 

SipURI toAddress = addressFactory.createSipURI(username, address); 
Address toNameAddress = addressFactory.createAddress(toAddress); 
toNameAddress.setDisplayName(username); 
ToHeader toHeader = headerFactory.createToHeader(toNameAddress, null); 

SipURI requestURI = addressFactory.createSipURI(username, address); 
requestURI.setTransportParam("udp"); 

ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>(); 
ViaHeader viaHeader = headerFactory.createViaHeader(getHost(), getPort(), "udp", "branch1"); 
viaHeaders.add(viaHeader); 

CallIdHeader callIdHeader = sipProvider.getNewCallId(); 

CSeqHeader cSeqHeader = headerFactory.createCSeqHeader(1, Request.MESSAGE); 

MaxForwardsHeader maxForwards = headerFactory.createMaxForwardsHeader(70); 

Request request = messageFactory.createRequest(requestURI, 
Request.MESSAGE, callIdHeader, cSeqHeader, fromHeader, 
toHeader, viaHeaders, maxForwards); 

SipURI contactURI = addressFactory.createSipURI(getUsername(), getHost()); 
contactURI.setPort(getPort()); 
Address contactAddress = addressFactory.createAddress(contactURI); 
contactAddress.setDisplayName(getUsername()); 
ContactHeader contactHeader = headerFactory.createContactHeader(contactAddress);
request.addHeader(contactHeader); 

ContentTypeHeader contentTypeHeader = headerFactory.createContentTypeHeader("text", "plain"); 
request.setContent(message, contentTypeHeader); 

sipProvider.sendRequest(request); 


/** This method is called by the SIP stack when a response arrives. */ 
public void processResponse(ResponseEvent evt) { 
Response response = evt.getResponse(); 
int status = response.getStatusCode(); 

if ((status >= 200) && (status < 300)) { // Success! 
messageProcessor.processInfo("--Sent"); 
return; 


messageProcessor.processError("Previous message not sent: " + status); 


/** 
* This method is called by the SIP stack when a new request arrives. 
*/ 
public void processRequest(RequestEvent evt) { 
Request req = evt.getRequest(); 

String method = req.getMethod(); 
if (!method.equals("MESSAGE")) { // bad request type. 
messageProcessor.processError("Bad request type: " + method); 
return; 


FromHeader from = (FromHeader) req.getHeader("From"); 
messageProcessor.processMessage(from.getAddress().toString(), 
new String(req.getRawContent())); 
Response response = null; 
try { // Reply with OK 
response = messageFactory.createResponse(200, req); 
ToHeader toHeader = (ToHeader) response.getHeader(ToHeader.NAME); 
toHeader.setTag("888"); // This is mandatory as per the spec. 
ServerTransaction st = sipProvider.getNewServerTransaction(req); 
st.sendResponse(response); 
} catch (Throwable e) { 
e.printStackTrace(); 
messageProcessor.processError("Can't send OK reply."); 



/** 
* This method is called by the SIP stack when there's no answer to a 
* message. Note that this is treated differently from an error message. 
*/ 
public void processTimeout(TimeoutEvent evt) { 
messageProcessor 
.processError("Previous message not sent: " + "timeout"); 


/** 
* This method is called by the SIP stack when there's an asynchronous 
* message transmission error. 
*/ 
public void processIOException(IOExceptionEvent evt) { 
messageProcessor.processError("Previous message not sent: " + "I/O Exception"); 


/** 
* This method is called by the SIP stack when a dialog (session) ends. 
*/ 
public void processDialogTerminated(DialogTerminatedEvent evt) { 


/** 
* This method is called by the SIP stack when a transaction ends. 
*/ 
public void processTransactionTerminated(TransactionTerminatedEvent evt) { 


public String getHost() { 
int port = sipProvider.getListeningPoint().getPort(); 
String host = sipStack.getIPAddress(); 
return host; 


public int getPort() { 
int port = sipProvider.getListeningPoint().getPort(); 
return port; 


public String getUsername() { 
return username; 


public void setUsername(String newUsername) { 
username = newUsername; 


public MessageProcessor getMessageProcessor() { 
return messageProcessor; 


public void setMessageProcessor(MessageProcessor newMessageProcessor) { 
messageProcessor = newMessageProcessor; 




TextClient.java : 

import java.awt.event.*; 
import javax.swing.*; 
import java.net.InetAddress; 

public class TextClient extends JFrame implements MessageProcessor { 
private SipLayer sipLayer; 

private JTextField fromAddress; 
private JLabel fromLbl; 
private JLabel receivedLbl; 
private JTextArea receivedMessages; 
private JScrollPane receivedScrollPane; 
private JButton sendBtn; 
private JLabel sendLbl; 
private JTextField sendMessages; 
private JTextField toAddress; 
private JLabel toLbl; 

public static void main(String[] args) { 
if (args.length != 2) { 
printUsage(); 
System.exit(-1); 


try { 
String username = args[0]; 
int port = Integer.parseInt(args[1]); 
String ip = InetAddress.getLocalHost().getHostAddress(); 

System.out.println("--username = "+username 
+"\n--port = "+port 
+"\n--ip = "+ip); 

SipLayer sipLayer = new SipLayer(username, ip, port); 
TextClient tc = new TextClient(sipLayer); 
sipLayer.setMessageProcessor(tc); 

// tc.show(); 
tc.setVisible(true); 
} catch (Throwable e) { 
System.out.println("Problem initializing the SIP stack."); 
e.printStackTrace(); 
System.exit(-1); 



private static void printUsage() { 
System.out.println("Syntax:"); 
System.out.println("  java -jar textclient.jar <username> <port>"); 
System.out.println("where <username> is the nickname of this user"); 
System.out.println("and <port> is the port number to use. Usually 5060 if not used by another process."); 
System.out.println("Example:"); 
System.out.println("  java -jar textclient.jar snoopy71 5061"); 


public TextClient(SipLayer sip) { 
super(); 
sipLayer = sip; 
initWindow(); 
String from = "sip:" + sip.getUsername() + "@" + sip.getHost() + ":" + sip.getPort(); 
this.fromAddress.setText(from); 


private void initWindow() { 
receivedLbl = new JLabel(); 
sendLbl = new JLabel(); 
sendMessages = new JTextField(); 
receivedScrollPane = new JScrollPane(); 
receivedMessages = new JTextArea(); 
fromLbl = new JLabel(); 
fromAddress = new JTextField(); 
toLbl = new JLabel(); 
toAddress = new JTextField(); 
sendBtn = new JButton(); 

getContentPane().setLayout(null); 

setTitle("TextClient"); 
addWindowListener(new WindowAdapter() { 
public void windowClosing(WindowEvent evt) { 
System.exit(0); 

}); 

receivedLbl.setText("Received Messages:"); 
receivedLbl.setAlignmentY(0.0F); 
receivedLbl.setPreferredSize(new java.awt.Dimension(25, 100)); 
getContentPane().add(receivedLbl); 
receivedLbl.setBounds(5, 0, 136, 20); 

sendLbl.setText("Send Message:"); 
getContentPane().add(sendLbl); 
sendLbl.setBounds(5, 150, 90, 20); 

getContentPane().add(sendMessages); 
sendMessages.setBounds(5, 170, 270, 20); 

receivedMessages.setAlignmentX(0.0F); 
receivedMessages.setEditable(false); //设置为不可编辑 
receivedMessages.setLineWrap(true); //设置可换行 
receivedMessages.setWrapStyleWord(true);//设置换行方式为单词边界换行 
receivedScrollPane.setViewportView(receivedMessages); 
receivedScrollPane 
.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); 

getContentPane().add(receivedScrollPane); 
receivedScrollPane.setBounds(5, 20, 270, 130); 

fromLbl.setText("From:"); 
getContentPane().add(fromLbl); 
fromLbl.setBounds(5, 200, 35, 15); 

getContentPane().add(fromAddress); 
fromAddress.setBounds(40, 200, 235, 20); 
fromAddress.setEditable(false); 

toLbl.setText("To:"); 
getContentPane().add(toLbl); 
toLbl.setBounds(5, 225, 35, 15); 

getContentPane().add(toAddress); 
toAddress.setBounds(40, 225, 235, 21); 

sendBtn.setText("Send"); 
sendBtn.addActionListener(new ActionListener() { 
public void actionPerformed(ActionEvent evt) { 
sendBtnActionPerformed(evt); 

}); 

getContentPane().add(sendBtn); 
sendBtn.setBounds(200, 255, 75, 25); 

java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit() 
.getScreenSize(); 
setBounds((screenSize.width - 288) / 2, (screenSize.height - 310) / 2, 
288, 320); 


private void sendBtnActionPerformed(ActionEvent evt) { 

try { 
String to = this.toAddress.getText(); 
String message = this.sendMessages.getText(); 
sipLayer.sendMessage(to, message); 
} catch (Throwable e) { 
e.printStackTrace(); 
this.receivedMessages.append("ERROR sending message: " 
+ e.getMessage() + "\n"); 




public void processMessage(String sender, String message) { 
this.receivedMessages.append("From " + sender + ": " + message + "\n"); 


public void processError(String errorMessage) { 
this.receivedMessages.append("ERROR: " + errorMessage + "\n"); 


public void processInfo(String infoMessage) { 
this.receivedMessages.append(infoMessage + "\n"); 




上面是一个简单的发送接收程序哈。 
运行截图: 



注意这里的ip和port是由电脑上获取的,要是你的程序不能运行,那可能是你的电脑没有连接、或者是连接断开。可以自行在程序中设置ip和port。 

对这个程序的说明: 
注意:这是一个本机发送本机接收的例子。 

对于整个程序的分析: 
* 在运行程序的时候,将自动获取发送方的username--bob、port--8000、ip--192.168.88.1 
* 定义一个SipLayer变量sipLayer,传入参数(username、portip), 
再将其传递给TextClient类的构造函数---这样在TextClient类中就可以调用SipLayer中的函数 
* 定义一个TextClient类TC,并将其传入sipLayer.setMessageProcessor(TC)--这一步很重要 
* 因为TextClient类实现了MessageProcessor接口,当SipLayer类中调用MessageProcessor中的函数时, 
参数自动传递到TextClient类中实现的MessageProcessor接口的函数 
* 进行窗口的初始化 
* 点击发送按钮的时候,将消失发送到SipLayer中进行处理:sipLayer.sendMessage(to, message); 
* 对数据进行包装和处理---这一步就不细说了 
* 最后由sip供应商发送数据sipProvider.sendRequest(request); 
* 因为之前说过了,这是一个本机发送本机接收的例子 
* 数据在SipLayer类中的processRequest(RequestEvent evt)函数接收到,并进行处理 

运行结果: 
* 在输入为:df:jo@192.168.88.1:8000时,程序运行正常 
* 在输入为::@192.168.88.1:8000时,程序运行正常 

* 在改变ip前三位的任意数时,例::@191.168.88.1:8000 
报错ERROR sending message: IO Exception occured while Sending Request 
* 在改变ip的最后一位时,不能接收数据,无报错 

* 在改变端口号时,例::@192.168.88.1:8001,不能接收数据,无报错 
* 在发送数据为空时,不能接收数据,无报错 
* 在去掉第一个":"时,例:sipjo@192.168.88.1:8000 
报错ERROR sending message: String index out of range: -14 
* 在去掉"@"时,例:sip:jo192.168.88.1:8000 
报错ERROR sending message: String index out of range: -5 

* 在第一个":"后面加上空格,例:sip: jo@192.168.88.1:8000 
报错ERROR sending message: sip: jo@192.168.88.1:8000: Missing host name 
* 在sip后面加上空格,程序正常运行 
* 在用户名后面加上空格,例:sip:jo @192.168.88.1:8000 
报错ERROR sending message: IO Exception occured while Sending Request 
* 在@后面加上空格,例:sip:jo@ 192.168.88.1:8000 

报错ERROR sending message: sip:jo@ 192.168.88.1:8000: Missing host name



转载于:http://kiddsunhaibo1.iteye.com/blog/1319995

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值