⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 transportmanager.java

📁 Peers is a very minimalistic SIP User-Agent. It s a softphone, written in java, and it has been test
💻 JAVA
字号:
/*    This file is part of Peers.    This program is free software: you can redistribute it and/or modify    it under the terms of the GNU General Public License as published by    the Free Software Foundation, either version 3 of the License, or    any later version.    This program is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    GNU General Public License for more details.    You should have received a copy of the GNU General Public License    along with this program.  If not, see <http://www.gnu.org/licenses/>.        Copyright 2007, 2008 Yohann Martineau */package net.sourceforge.peers.sip.transport;import static net.sourceforge.peers.sip.RFC3261.DEFAULT_SIP_VERSION;import static net.sourceforge.peers.sip.RFC3261.IPV4_TTL;import static net.sourceforge.peers.sip.RFC3261.PARAM_MADDR;import static net.sourceforge.peers.sip.RFC3261.PARAM_TTL;import static net.sourceforge.peers.sip.RFC3261.TRANSPORT_DEFAULT_PORT;import static net.sourceforge.peers.sip.RFC3261.TRANSPORT_PORT_SEP;import static net.sourceforge.peers.sip.RFC3261.TRANSPORT_SCTP;import static net.sourceforge.peers.sip.RFC3261.TRANSPORT_TCP;import static net.sourceforge.peers.sip.RFC3261.TRANSPORT_TLS_PORT;import static net.sourceforge.peers.sip.RFC3261.TRANSPORT_UDP;import static net.sourceforge.peers.sip.RFC3261.TRANSPORT_UDP_USUAL_MAX_SIZE;import static net.sourceforge.peers.sip.RFC3261.TRANSPORT_VIA_SEP;import static net.sourceforge.peers.sip.RFC3261.TRANSPORT_VIA_SEP2;import java.io.IOException;import java.net.DatagramSocket;import java.net.Inet4Address;import java.net.InetAddress;import java.net.UnknownHostException;import java.util.Hashtable;import net.sourceforge.peers.Logger;import net.sourceforge.peers.sip.RFC3261;import net.sourceforge.peers.sip.Utils;import net.sourceforge.peers.sip.syntaxencoding.SipHeaderFieldName;import net.sourceforge.peers.sip.syntaxencoding.SipHeaderFieldValue;import net.sourceforge.peers.sip.syntaxencoding.SipHeaderParamName;import net.sourceforge.peers.sip.syntaxencoding.SipHeaders;import net.sourceforge.peers.sip.syntaxencoding.SipParser;public class TransportManager {    private static TransportManager INSTANCE;    private static int NO_TTL = -1;        public static TransportManager getInstance() {        if (INSTANCE == null) {            INSTANCE = new TransportManager();        }        return INSTANCE;    }        protected SipParser sipParser;        private Hashtable<SipTransportConnection, DatagramSocket> datagramSockets;    private Hashtable<SipTransportConnection, MessageSender> messageSenders;    private Hashtable<SipTransportConnection, MessageReceiver> messageReceivers;        private TransportManager() {        sipParser = new SipParser();        datagramSockets = new Hashtable<SipTransportConnection, DatagramSocket>();        messageSenders = new Hashtable<SipTransportConnection, MessageSender>();        messageReceivers = new Hashtable<SipTransportConnection, MessageReceiver>();    }        public MessageSender createClientTransport(SipRequest sipRequest,            InetAddress inetAddress, int port, String transport)                throws IOException {        return createClientTransport(sipRequest, inetAddress, port, transport,                NO_TTL);    }        public MessageSender createClientTransport(SipRequest sipRequest,            InetAddress inetAddress, int port, String transport, int ttl)                throws IOException {        //18.1                //via created by transaction layer to add branchid        SipHeaderFieldValue via = Utils.getInstance().getTopVia(sipRequest);        StringBuffer buf = new StringBuffer(DEFAULT_SIP_VERSION);        buf.append(TRANSPORT_VIA_SEP);        if (sipRequest.toString().getBytes().length > TRANSPORT_UDP_USUAL_MAX_SIZE) {            transport = TRANSPORT_TCP;        }        buf.append(transport);        if (inetAddress.isMulticastAddress()) {            SipHeaderParamName maddrName = new SipHeaderParamName(PARAM_MADDR);            via.addParam(maddrName, inetAddress.getHostAddress());            if (inetAddress instanceof Inet4Address) {                SipHeaderParamName ttlName = new SipHeaderParamName(PARAM_TTL);                via.addParam(ttlName, IPV4_TTL);            }        }        buf.append(TRANSPORT_VIA_SEP2);//space                //TODO user server connection                //TODO make local address and local port configurable        InetAddress localAddress = Utils.getInstance().getMyAddress();        int localPort = Utils.getInstance().getSipPort();                        buf.append(localAddress.getHostAddress()); //TODO use getHostName if real DNS        buf.append(TRANSPORT_PORT_SEP);                if (localPort < 1) {            //use default port            if (TRANSPORT_TCP.equals(transport) || TRANSPORT_UDP.equals(transport)                    || TRANSPORT_SCTP.equals(transport)) {                localPort = TRANSPORT_DEFAULT_PORT;            }            else if (TRANSPORT_SCTP.equals(transport)) {                localPort = TRANSPORT_TLS_PORT;            }            else {                throw new RuntimeException("unknown transport type");            }        }        buf.append(localPort);//no, this port must be configured        //TODO add sent-by (p. 143) Before...                via.setValue(buf.toString());                SipTransportConnection connection =            new SipTransportConnection(inetAddress, port, transport);        MessageSender messageSender = messageSenders.get(connection);        if (messageSender == null) {            messageSender = createMessageSender(connection);        }        return messageSender;    }            public void createServerTransport(String transportType, int port)            throws IOException {        SipTransportConnection conn = new SipTransportConnection(                    Utils.getInstance().getMyAddress(), port, transportType);                MessageReceiver messageReceiver = messageReceivers.get(conn);        if (messageReceiver == null) {            messageReceiver = createMessageReceiver(conn);            new Thread(messageReceiver).start();        }        if (!messageReceiver.isListening()) {            new Thread(messageReceiver).start();        }    }        public void sendResponse(SipResponse sipResponse) throws IOException {        //18.2.2        SipHeaderFieldValue topVia = Utils.getInstance().getTopVia(sipResponse);        String topViaValue = topVia.getValue();        StringBuffer buf = new StringBuffer(topViaValue);        String hostport = null;        int i = topViaValue.length() - 1;        while (i > 0) {            char c = buf.charAt(i);            if (c == ' ' || c == '\t') {                hostport = buf.substring(i + 1);                break;            }            --i;        }        if (hostport == null) {            throw new RuntimeException("host or ip address not found in top via");        }        String host;        int port;        int colonPos = hostport.indexOf(RFC3261.TRANSPORT_PORT_SEP);        if (colonPos > -1) {            host = hostport.substring(0, colonPos);            port = Integer.parseInt(                    hostport.substring(colonPos + 1, hostport.length()));        } else {            host = hostport;            port = RFC3261.TRANSPORT_DEFAULT_PORT;        }                String transport;        if (buf.indexOf(RFC3261.TRANSPORT_TCP) > -1) {            transport = RFC3261.TRANSPORT_TCP;        } else if (buf.indexOf(RFC3261.TRANSPORT_UDP) > -1) {            transport = RFC3261.TRANSPORT_UDP;        } else {            System.err.println("no transport found in top via header," +                    " discarding response");            return;        }                String received =            topVia.getParam(new SipHeaderParamName(RFC3261.PARAM_RECEIVED));        if (received != null) {            host = received;        }        SipTransportConnection connection;        try {            connection = new SipTransportConnection(                    InetAddress.getByName(host), port, transport);        } catch (UnknownHostException e) {            e.printStackTrace();            return;        }                //actual sending                //TODO manage maddr parameter in top via for multicast        if (buf.indexOf(RFC3261.TRANSPORT_TCP) > -1) {//            Socket socket = (Socket)factory.connections.get(connection);//            if (!socket.isClosed()) {//                try {//                    socket.getOutputStream().write(data);//                } catch (IOException e) {//                    e.printStackTrace();//                    return;//                    //TODO//                }//            } else {//                try {//                    socket = new Socket(host, port);//                    factory.connections.put(connection, socket);//                    socket.getOutputStream().write(data);//                } catch (IOException e) {//                    // TODO Auto-generated catch block//                    e.printStackTrace();//                    /*//                     * TODO//                     * If connection attempt fails, use the procedures in RFC3263//                     * for servers in order to determine the IP address and//                     * port to open the connection and send the response to.//                     *///                    return;//                }//            }        } else {            MessageSender messageSender = messageSenders.get(connection);            if (messageSender == null) {                messageSender = createMessageSender(connection);            }            //add contact header            SipHeaderFieldName contactName = new SipHeaderFieldName(RFC3261.HDR_CONTACT);            SipHeaders respHeaders = sipResponse.getSipHeaders();            StringBuffer contactBuf = new StringBuffer();            contactBuf.append(RFC3261.LEFT_ANGLE_BRACKET);            contactBuf.append(RFC3261.SIP_SCHEME);            contactBuf.append(RFC3261.SCHEME_SEPARATOR);            contactBuf.append(messageSender.getContact());            contactBuf.append(RFC3261.RIGHT_ANGLE_BRACKET);            respHeaders.add(contactName, new SipHeaderFieldValue(contactBuf.toString()));            messageSender.sendMessage(sipResponse);        }                    }        private MessageSender createMessageSender(SipTransportConnection conn)            throws IOException {        MessageSender messageSender = null;        Object socket = null;        if (RFC3261.TRANSPORT_UDP.equalsIgnoreCase(conn.getRemoteTransport())) {            //TODO use Utils.getMyAddress to create socket on appropriate NIC            DatagramSocket datagramSocket = datagramSockets.get(conn);            if (datagramSocket == null) {                datagramSocket = new DatagramSocket();                datagramSockets.put(conn, datagramSocket);                Logger.getInstance().info("added datagram socket " + conn);            }            socket = datagramSocket;            messageSender = new UdpMessageSender(conn.getRemoteInetAddress(),                    conn.getRemotePort(), datagramSocket);        } else {            // TODO            // messageReceiver = new TcpMessageReceiver(port);        }        messageSenders.put(conn, messageSender);        //when a mesage is sent over a transport, the transport layer        //must also be able to receive messages on this transport        SipTransportConnection serverConn = new SipTransportConnection(                Utils.getInstance().getMyAddress(),                messageSender.getLocalPort(),                conn.getRemoteTransport());                MessageReceiver messageReceiver =            createMessageReceiver(serverConn, socket);        new Thread(messageReceiver).start();        return messageSender;    }        private MessageReceiver createMessageReceiver(SipTransportConnection conn,            Object socket) throws IOException {        MessageReceiver messageReceiver = null;        if (RFC3261.TRANSPORT_UDP.equalsIgnoreCase(conn.getRemoteTransport())) {            DatagramSocket datagramSocket = (DatagramSocket)socket;            messageReceiver = new UdpMessageReceiver(datagramSocket);        }        messageReceivers.put(conn, messageReceiver);        return messageReceiver;    }        private MessageReceiver createMessageReceiver(SipTransportConnection conn)            throws IOException {        MessageReceiver messageReceiver = null;        Logger.getInstance().info("adding " + conn + ": " + messageReceiver                    + " to message receivers");        if (RFC3261.TRANSPORT_UDP.equals(conn.getRemoteTransport())) {            DatagramSocket datagramSocket = datagramSockets.get(conn);            if (datagramSocket == null) {                datagramSocket = new DatagramSocket(conn.getRemotePort());                datagramSockets.put(conn, datagramSocket);                Logger.getInstance().info("added datagram socket " + conn);            }            messageReceiver = new UdpMessageReceiver(datagramSocket);            //TODO create also tcp receiver using a recursive call        } else {            //TODO            //messageReceiver = new TcpMessageReceiver(port);        }        messageReceivers.put(conn, messageReceiver);        return messageReceiver;    }        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -