All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sourceforge.jtds.jdbc.MSSqlServerInfo Maven / Gradle / Ivy

Go to download

jTDS is an open source 100% pure Java (type 4) JDBC 3.0 driver for Microsoft SQL Server (6.5, 7, 2000, 2005, 2008, 2012) and Sybase ASE (10, 11, 12, 15). jTDS is based on FreeTDS and is currently the fastest production-ready JDBC driver for SQL Server and Sybase. jTDS is 100% JDBC 3.0 compatible, supporting forward-only and scrollable/updateable ResultSets and implementing all the DatabaseMetaData and ResultSetMetaData methods.

There is a newer version: 1.3.1
Show newest version
// jTDS JDBC Driver for Microsoft SQL Server and Sybase
// Copyright (C) 2004 The jTDS Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library 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
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
package net.sourceforge.jtds.jdbc;

import java.io.InterruptedIOException;
import java.sql.SQLException;
import java.net.*;

import net.sourceforge.jtds.util.Logger;

/**
 * This class communicates with SQL Server 2k to determine what ports its
 * instances are listening to. It does this by sending a UDP packet with the
 * byte 0x02 in it, and parsing the response.
 * 

* An example of the return packet format is as follows: *

 * < 00000000 05 ea 00 53 65 72 76 65 72 4e 61 6d 65 3b 42 52 # ...ServerName;BR
 * < 00000010 49 4e 4b 4c 45 59 3b 49 6e 73 74 61 6e 63 65 4e # INKLEY;InstanceN
 * < 00000020 61 6d 65 3b 4d 53 53 51 4c 53 45 52 56 45 52 3b # ame;MSSQLSERVER;
 * < 00000030 49 73 43 6c 75 73 74 65 72 65 64 3b 4e 6f 3b 56 # IsClustered;No;V
 * < 00000040 65 72 73 69 6f 6e 3b 38 2e 30 30 2e 31 39 34 3b # ersion;8.00.194;
 * < 00000050 74 63 70 3b 31 34 33 33 3b 6e 70 3b 5c 5c 42 52 # tcp;1433;np;\\BR
 * < 00000060 49 4e 4b 4c 45 59 5c 70 69 70 65 5c 73 71 6c 5c # INKLEY\pipe\sql\
 * < 00000070 71 75 65 72 79 3b 3b 53 65 72 76 65 72 4e 61 6d # query;;ServerNam
 * < 00000080 65 3b 42 52 49 4e 4b 4c 45 59 3b 49 6e 73 74 61 # e;BRINKLEY;Insta
 * < 00000090 6e 63 65 4e 61 6d 65 3b 44 4f 47 3b 49 73 43 6c # nceName;DOG;IsCl
 * < 000000a0 75 73 74 65 72 65 64 3b 4e 6f 3b 56 65 72 73 69 # ustered;No;Versi
 * < 000000b0 6f 6e 3b 38 2e 30 30 2e 31 39 34 3b 74 63 70 3b # on;8.00.194;tcp;
 * < 000000c0 33 35 34 36 3b 6e 70 3b 5c 5c 42 52 49 4e 4b 4c # 3546;np;\\BRINKL
 * < 000000d0 45 59 5c 70 69 70 65 5c 4d 53 53 51 4c 24 44 4f # EY\pipe\MSSQL$DO
 * < 000000e0 47 5c 73 71 6c 5c 71 75 65 72 79 3b 3b          # G\sql\query;;
 * 
* * @author Matt Brinkley * @version $Id: MSSqlServerInfo.java,v 1.8.2.1 2009-07-30 10:50:05 ickzon Exp $ */ public class MSSqlServerInfo { private final int numRetries = 3; private final int timeout = 2000; private String[] serverInfoStrings; public MSSqlServerInfo(String host) throws SQLException { DatagramSocket socket = null; try { InetAddress addr = InetAddress.getByName(host); socket = new DatagramSocket(); byte[] msg = new byte[] {0x02}; DatagramPacket requestp = new DatagramPacket(msg, msg.length, addr, 1434); socket.setSoTimeout(timeout); for (int i = 0; i < numRetries; i++) { try { DatagramPacket responsep; byte[] buf = new byte[0]; // init with an array of length 0, will be expanded with every iteration int length; do { buf = new byte[buf.length + 4096]; responsep = new DatagramPacket(buf, buf.length); socket.send(requestp); socket.receive(responsep); length = responsep.getLength(); } while(length==buf.length); // retry until the whole server response can be buffered String infoString = extractString(buf, length); serverInfoStrings = split(infoString, ';'); return; } catch (InterruptedIOException toEx) { if (Logger.isActive()) { Logger.logException(toEx); } } } } catch (Exception e) { if (Logger.isActive()) { Logger.logException(e); } } finally { if (socket != null) { socket.close(); } } throw new SQLException( Messages.get("error.msinfo.badinfo", host), "HY000"); } /** * Call getInfo() before calling this method. It parses the info string * returned from SQL Server and looks for the port for the given named * instance. If it can't be found, or if getInfo() hadsn't been called, * it returns -1. * * @param instanceName * @return port the given instance is listening on, or -1 if it can't be * found. */ public int getPortForInstance(String instanceName) throws SQLException { if (serverInfoStrings == null) { return -1; } // NOTE: default instance is called MSSQLSERVER if (instanceName == null || instanceName.length() == 0) { instanceName = "MSSQLSERVER"; } String curInstance = null; String curPort = null; // format: "ServerName,HOSTNAME,InstanceName,INSTANCENAME,IsClustered,No,Version,9.00.1399.06,tcp,PORT,np;\HOSTNAME\pipe\MSSQL$HOSTNAME\sql, ," for (int index = 0; index < serverInfoStrings.length; index++) { if (serverInfoStrings[index].length() == 0) { curInstance = null; curPort = null; } else { String key = serverInfoStrings[index]; String value = ""; index++; if (index < serverInfoStrings.length) { value = serverInfoStrings[index]; } if ("InstanceName".equals(key)) { curInstance = value; } if ("tcp".equals(key)) { curPort = value; } if (curInstance != null && curPort != null && curInstance.equalsIgnoreCase(instanceName)) { try { return Integer.parseInt(curPort); } catch (NumberFormatException e) { throw new SQLException( Messages.get("error.msinfo.badport", instanceName), "HY000"); } } } } // didn't find it... return -1; } private static final String extractString(byte[] buf, int len) { // the first three bytes are unknown; after that, it should be a narrow string... final int headerLength = 3; return new String(buf, headerLength, len - headerLength); } public static String[] split(String s, int ch) { int size = 0; for (int pos = 0; pos != -1; pos = s.indexOf(ch, pos + 1), size++); String res[] = new String[size]; int i = 0; int p1 = 0; int p2 = s.indexOf(ch); do { res[i++] = s.substring(p1, p2 == -1 ? s.length() : p2); p1 = p2 + 1; p2 = s.indexOf(ch, p1); } while (p1 != 0); return res; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy