双工RTP连接从一端调用时在JMF中建立,但从另一端调用时到达不可达端口



我使用JMF为使用JAIN-SIP的应用程序发送和接收音频,下面是我的代码:

import com.sun.media.rtp.RTPSessionMgr;
import java.io.IOException;
import java.net.InetAddress;
import java.net.URL;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.media.*;
import javax.media.format.AudioFormat;
import javax.media.format.UnsupportedFormatException;
import javax.media.protocol.ContentDescriptor;
import javax.media.protocol.DataSource;
import javax.media.rtp.InvalidSessionAddressException;
import javax.media.rtp.ReceiveStream;
import javax.media.rtp.ReceiveStreamListener;
import javax.media.rtp.SendStream;
import javax.media.rtp.SessionAddress;
import javax.media.rtp.event.NewReceiveStreamEvent;
import javax.media.rtp.event.ReceiveStreamEvent;
 import java.net.*;
import javax.media.control.TrackControl;
 import javax.media.rtp.*;
import com.sun.media.rtp.*;
import javax.media.rtp.RTPManager;

/**
*
* @author dexter
*/
public class Transmitter extends Thread implements ReceiveStreamListener  {
   static Processor mp;
   static DataSink ds;
     String ip,port;
     RTPManager rtp;
     SendStream ss;
     ReceiveStream rs;
     DataSource rds,ods,source;
      Player player;
      SessionAddress remoteaddr;
   public void run()
   {
       try {
           Format[] formats= new Format[]{new AudioFormat(AudioFormat.ULAW_RTP)};
           ContentDescriptor cd= new ContentDescriptor(ContentDescriptor.RAW_RTP);
           Vector devices= CaptureDeviceManager.getDeviceList(new
AudioFormat("linear",8000,16,2));
            System.out.println("devices="+devices);

           CaptureDeviceInfo di=(CaptureDeviceInfo) devices.firstElement();
System.out.println("device info="+di);
           MediaLocator ml= di.getLocator();
System.out.println("locator="+ml);
try {
                source = javax.media.Manager.createDataSource(ml);
            }
            catch (Exception e) {
                // Try JavaSound Locator as a last resort
                try {
                    source= javax.media.Manager.createDataSource(new MediaLocator("javasound://"));
                }
                catch (Exception ee) {
                    System.err.println("Couldn't create DataSource");
                }
            }
           mp=Manager.createRealizedProcessor(new ProcessorModel(source,formats,cd));
           mp.start();
          rtp=RTPManager.newInstance();
         // rtp.addReceiveStreamListener((ReceiveStreamListener) this);
       SessionAddress localaddr= new SessionAddress(InetAddress.getByName(Phone.ip),Integer.parseInt(SipLayer.caller_port));
           remoteaddr= new SessionAddress(InetAddress.getByName(ip),new Integer(port));
          rtp.initialize(localaddr);
          rtp.addReceiveStreamListener(this);
         rtp.addTarget(remoteaddr);

          ss=rtp.createSendStream(mp.getDataOutput(),0);
     //     mp.start();
          ss.start();
       } catch (UnsupportedFormatException ex) {
            Logger.getLogger(Transmitter.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvalidSessionAddressException ex) {
            Logger.getLogger(Transmitter.class.getName()).log(Level.SEVERE, null, ex);
        }  catch (CannotRealizeException ex) {
            Logger.getLogger(Transmitter.class.getName()).log(Level.SEVERE, null, ex);
        }  catch (IOException ex) {
           Logger.getLogger(Transmitter.class.getName()).log(Level.SEVERE, null, ex);
       } catch (NoProcessorException ex) {
           Logger.getLogger(Transmitter.class.getName()).log(Level.SEVERE, null, ex);
       } 
   }
   public  Transmitter(String callee_ip,String callee_port)
{
    ip=callee_ip;
    port= callee_port;
}
    public void update(ReceiveStreamEvent rse) {
        if(rse instanceof NewReceiveStreamEvent)
        {
            try {
                 rs = rse.getReceiveStream();
                rds = rs.getDataSource();
                player = Manager.createPlayer(rds);
                player.start();
            } catch (IOException ex) {
                Logger.getLogger(Transmitter.class.getName()).log(Level.SEVERE, null, ex);
            } catch (NoPlayerException ex) {
                Logger.getLogger(Transmitter.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }
    public void stop_media()
    {
        try{
            player.stop();
            player.deallocate();
            player.close();
            ss.stop();
          // necessary for sending rtcp bye
            mp.stop();
            mp.close();
            mp.deallocate();
            ss.close();
         //   
            rtp.removeTarget(remoteaddr," disconnected");
            rtp.dispose();
        }catch(Exception e){
        }
    }
}

问题是:当我创建一个连接从我的应用程序(i。(我打电话)没有问题,我可以发送和接收音频。但当我接到电话时,我能听到对方的声音,但对方听不见听到我。在wireshark中,目标端口不可达。请建议这个问题的解决方案是什么,为什么会出现这个问题。

无论如何,我已经解决了这个问题,我认为这是很多人的问题,所以请不要删除它。出现"端口不可达"的原因很简单:您分配的端口可能已被使用,或者您可能忽略了RTP需要偶数端口来发送数据,而RTCP需要奇数端口。并且RTCP由JMF自动处理。因此,只需找到一个未使用的偶数UDP端口并使用它发送RTP。另外,如果无法接收任何数据包(SIP或RTP),则禁用防火墙

public static int findFreePort() {
        DatagramSocket socket = null;
                int port=1;
        try {
                    while(port%2!=0)
                    {
                        socket = new DatagramSocket(0);
            socket.setReuseAddress(true);
             port = socket.getLocalPort();
                         socket.close();
                    }   
            return port;
        } catch (IOException e) { 
        } finally {
            if (socket != null) {
                            socket.close();
            }
        }
        throw new IllegalStateException("Could not find a free UDP port to start");
    }

相关内容

  • 没有找到相关文章

最新更新