001/** 002 * 003 * Copyright the original author or authors 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.jivesoftware.smackx.jingle.nat; 018 019import java.io.IOException; 020import java.io.InputStream; 021import java.io.OutputStream; 022import java.net.DatagramPacket; 023import java.net.DatagramSocket; 024import java.net.InetAddress; 025import java.net.Socket; 026import java.util.logging.Logger; 027 028/** 029 * A Simple and Experimental Bridge. 030 * It Creates a TCP Socket That Connects to another TCP Socket Listener and forwards every packets received to an UDP Listener. 031 * And forwards every packets received in UDP Socket, to the TCP Server 032 */ 033public class TcpUdpBridgeClient { 034 035 private static final Logger LOGGER = Logger.getLogger(TcpUdpBridgeClient.class.getName()); 036 037 private String remoteTcpHost = null; 038 private String remoteUdpHost = null; 039 private int remoteTcpPort = -1; 040 private int remoteUdpPort = -1; 041 private int localUdpPort = -1; 042 043 private DatagramSocket localUdpSocket; 044 private Socket localTcpSocket; 045 046 public TcpUdpBridgeClient(String remoteTcpHost, String remoteUdpHost, int remoteTcpPort, int remoteUdpPort) { 047 this.remoteTcpHost = remoteTcpHost; 048 this.remoteUdpHost = remoteUdpHost; 049 this.remoteTcpPort = remoteTcpPort; 050 this.remoteUdpPort = remoteUdpPort; 051 052 try { 053 localTcpSocket = new Socket(remoteTcpHost, remoteTcpPort); 054 localUdpSocket = new DatagramSocket(0); 055 localUdpPort = localUdpSocket.getLocalPort(); 056 LOGGER.fine("UDP: " + localUdpSocket.getLocalPort()); 057 } 058 catch (IOException e) { 059 e.printStackTrace(); 060 } 061 startBridge(); 062 } 063 064 public void startBridge() { 065 066 067 final Thread process = new Thread(new Runnable() { 068 069 public void run() { 070 try { 071 OutputStream out = localTcpSocket.getOutputStream(); 072 073 while (true) { 074 075 byte b[] = new byte[500]; 076 DatagramPacket p = new DatagramPacket(b, 500); 077 078 localUdpSocket.receive(p); 079 if (p.getLength() == 0) continue; 080 081 LOGGER.fine("UDP Client Received and Sending to TCP Server:"+new String(p.getData(),0,p.getLength(),"UTF-8")); 082 083 out.write(p.getData(), 0, p.getLength()); 084 out.flush(); 085 LOGGER.fine("Client Flush"); 086 087 } 088 089 } 090 catch (IOException e) { 091 e.printStackTrace(); 092 } 093 } 094 095 }); 096 097 new Thread(new Runnable() { 098 099 public void run() { 100 try { 101 102 InputStream in = localTcpSocket.getInputStream(); 103 InetAddress remoteHost = InetAddress.getByName(remoteUdpHost); 104 process.start(); 105 106 while (true) { 107 byte b[] = new byte[500]; 108 109 int s = in.read(b); 110 //if (s == -1) continue; 111 112 LOGGER.fine("TCP Client:" +new String(b,0,s,"UTF-8")); 113 114 DatagramPacket udpPacket = new DatagramPacket(b, s); 115 116 udpPacket.setAddress(remoteHost); 117 udpPacket.setPort(remoteUdpPort); 118 119 localUdpSocket.send(udpPacket); 120 121 } 122 123 } 124 catch (IOException e) { 125 e.printStackTrace(); 126 } 127 } 128 129 }).start(); 130 } 131 132 public Socket getLocalTcpSocket() { 133 return localTcpSocket; 134 } 135 136 public DatagramSocket getLocalUdpSocket() { 137 return localUdpSocket; 138 } 139}