2010年3月12日 星期五

[Linux Programming] 在 Ubuntu 中使用 C 語言連結 MySQL

首先.......必須安裝 MySQL server,一般來說安裝 "mysql-server" 都可以裝到目前最新版的套件

接著要安裝開發程式所需要的 library:

Ubuntu 8.04 => libmysqlclient15-dev

相關的 header 檔案都會放在 /usr/include/ 裡面,而實際運作的函式庫則會存在 /usr/lib/mysql

若是撰寫 mysql 相關程式時,編譯方式如下:

gcc <程式名稱> -I /usr/include/mysql -L /usr/lib/mysql -l mysqlclient -o <輸出檔案名稱>

2010年3月9日 星期二

[Git] 在 Windows 上使用 Git

Git 聽說是比 cvs, subversion 還好用的 version control system 阿!!

為何要用 Git 阿?? 因為優點很多阿! 詳細說明可以看 => Why Git is Better Than X  這一篇文章~

Git 大概有以下特色:
  1. 每個 local 端都有自己的 repository

  2. 特色為 branch + merge

  3. 適合開發人數眾多的大型專案(當然小型專案也是沒有問題滴)


大部分使用 git 的人都是在 Linux 的平台上使用,但要怎麼在 Windows 上面使用呢?

簡單說明步驟如下:
  1. 下載 Windows 用的 git 核心程式,在 git 官網上為 msysgit

  2. 在所要進行版本管理的資料夾上按滑鼠右鍵,選擇 Git Bash Here

  3. 接著會跳出一個模擬 bash 環境的視窗,接著就可以跟 Linux 一樣開始使用 Git 囉!


===== 以下說明最基本的使用方式 =====

#初始化 local repository
> git init

#將目錄中的檔案全部加入 Staging Area
> git add .

#將 Staging Area 中的檔案加入 local repository 中
> git commit -a

#移動至 master branch (正常狀況下 branch 會預設在 master)
> git checkout master

#將資料 push 至遠端的 repository (以 gitorious 為例)
> git remote add origin <git push url>
> git push origin master


【備註】
在將檔案 push 到遠端 git server 之前,需要把加密用的 key pair 準備好,可以透過以下指令產生:
> ssh-keygen -rsa
接著把兩個檔案都放到 C:\Documents and Settings\<USER NAME>\.ssh ,並將 public key 的內容加入到 gitorious 的網站上即可。


相關連結


2010年3月7日 星期日

[Linux Programming] 在 Ubuntu 中使用 dbm 資料庫

在 ubuntu 中 dbm 相關開發套件是不會預先安裝的,因此如果要使用的話,必須安裝「libgdbm-dev」套件。

而由於安裝的是 gdbm 套件,若要使用 gdbm 的相關函式當然沒問題,但若是要使用 ndbm 的相關函式,則必須進行相容性的轉換,作法如下:
  1. 在程式中 include gdbm-ndbm.h

  2. 編譯時加上 -l gdbm_compat -l gdbm 兩個參數以連結函式庫
函式庫說明可以參考以下連結:

2010年3月1日 星期一

[C#] Socket Programming

socket programming 的重點大概有幾個:
  1. 有 server & client 兩端
  2. server 只有一個,而 client 有可能會多個
  3. server 可設定監聽(listen)的 port number


以下直接用範例來說明囉!
(其中 SocketServer 跟新的 client 連線後,會交給 ClientRequestHandler 處理)

SocketServer.cs
using System;
using System.Collections.Generic;
using System.Text;

using System.Net.Sockets;
using System.Net;
using System.ComponentModel;

namespace SocketConn
{
    class SocketServer
    {
        #region private property

        ///         /// socket server TCP port number
        ///         private int _PortNumber;


        ///         /// TCP Listener
        ///         private TcpListener _Listener;


        ///         /// 用來處理 Listener 工作的執行緒
        ///         private BackgroundWorker _bgwServer = new BackgroundWorker();


        ///         /// socker client 識別編號
        ///         private int _ClientNo = 0;

        #endregion


        #region static public property

        ///         /// 工作進行中產生之訊息
        ///         public static List sMessages = new List();

        #endregion


        #region constructor

        ///         /// constructor
        ///         /// 
socket server TCP port number
        public SocketServer(int inPortNumber)
        {
            this._PortNumber = inPortNumber;

            //委派事件
            _bgwServer.DoWork += new DoWorkEventHandler(_bgwServer_DoWork);
        }

        #endregion


        #region public method

        ///         /// 開始監聽
        ///         public void Start()
        {
            if (!_bgwServer.IsBusy)
                _bgwServer.RunWorkerAsync();
        }

        #endregion


        #region BackgroundWorker

        /// 
        /// 處理 Listener 工作
        ///         /// 

        /// 

        private void _bgwServer_DoWork(object sender, DoWorkEventArgs e)
        {
            try
            {
                //若 TCP Listner 正在工作,則停止
                if (_Listener != null)
                    _Listener.Stop();

                //初始化 TCPListener
                _Listener = new TcpListener(IPAddress.Any, _PortNumber);

                //啟動 listener
                _Listener.Start();
                sMessages.Add(" >> " + "Server Started");

                //========== 持續接受監聽 socket client 的連線 ========== (start)
                while (true)
                {
                    //監聽到來自 socket client 的連線要求
                    TcpClient socket4Client = _Listener.AcceptTcpClient();

                    //累加 socket client 識別編號
                    _ClientNo++;
                    sMessages.Add(" >> " + "Client Request No:" + Convert.ToString(_ClientNo) + " started!");

                    //產生 BackgroundWorker 負責處理每一個 Socket Client 的要求
                    ClientRequestHandler handler = new ClientRequestHandler(_ClientNo, socket4Client);
                    handler.DoCommunicate();
                }
                //========== 持續接受監聽 socket client 的連線 ========== (end)
            }
            catch (Exception exp)
            {
                sMessages.Add(exp.ToString());
            }
        }

        #endregion
    }
}


ClientRequestHandler.cs
using System;
using System.Collections.Generic;
using System.Text;

using System.Net.Sockets;
using System.ComponentModel;

namespace SocketConn
{
    class ClientRequestHandler
    {
        #region private property

        ///         /// socket client 識別號碼
        ///         private int _ClientNo;


        ///         /// socket client reuqest
        ///         private TcpClient _TcpClient;

        #endregion


        #region constructor

        ///         /// constructor
        ///         /// 
socket client 識別號碼
        /// 
socket client reuqest
        public ClientRequestHandler(int inClientNo, TcpClient inTcpClient)
        {
            this._ClientNo = inClientNo;
            this._TcpClient = inTcpClient;
        }

        #endregion


        #region public method

        ///         /// server & client 間相互進行通訊
        ///         public void DoCommunicate()
        {
            //產生 BackgroundWorker 負責處理每一個 socket client 的 reuqest
            BackgroundWorker bgwSocket = new BackgroundWorker();
            bgwSocket.DoWork += new DoWorkEventHandler(bgwSocket_DoWork);
            bgwSocket.RunWorkerAsync();
        }

        #endregion


        #region BackgroundWorker

        ///         /// 處理 socket client request
        ///         private void bgwSocket_DoWork(object sender, DoWorkEventArgs e)
        {
            //server & client 已經連線完成
            while (_TcpClient.Connected)
            {
                //取得網路串流物件,取得來自 socket client 的訊息
                NetworkStream netStream = _TcpClient.GetStream();
                byte[] readBuffer = new byte[1024];
                int count = 0;
                if ((count = netStream.Read(readBuffer, 0, readBuffer.Length)) != 0)
                {
                    string clientRequest = Encoding.UTF8.GetString(readBuffer, 0, count);
                    SocketServer.sMessages.Add(" >> " + "From client(" + _ClientNo + ") =>" + clientRequest);

                    //正確取得 client requst,再回傳給 client
                    string serverResponse = "Server to clinet(" + _ClientNo + ") => message: " + clientRequest;
                    byte[] sendBytes = Encoding.UTF8.GetBytes(serverResponse);
                    netStream.Write(sendBytes, 0, sendBytes.Length);
                    netStream.Flush();
                    SocketServer.sMessages.Add(" >> " + serverResponse);
                }
            }
        }

        #endregion
    }
}


SocketClient.cs
using System;
using System.Collections.Generic;
using System.Text;

using System.Net;
using System.Net.Sockets;

namespace SocketConn
{
    class SocketClient
    {
        #region private property

        ///         /// 遠端 socket server IP 位址
        ///         private string _RemoteIpAddress;

        ///         /// 遠端 socket server 所監聽的 port number
        ///         private int _RemotePortNumber;


        ///         /// socket client 物件(連接遠端 socket server 用)
        ///         private TcpClient _TcpClient;

        #endregion


        #region public static property

        public static List sMessages = new List();

        #endregion


        #region constructor

        ///         /// constructor
        ///        /// 
遠端 socket server IP 位址
        /// 
遠端 socket server 所監聽的 port number
        public SocketClient(string inRemoteIpAddr, int inRemotePortNum)
        {
            this._RemoteIpAddress = inRemoteIpAddr;
            this._RemotePortNumber = inRemotePortNum;
        }

        #endregion


        #region public method

        ///         /// 連線至 socket server
        ///         public void Connect()
        {
            //初始化 socket client
            _TcpClient = new TcpClient();
            _TcpClient.Connect(_RemoteIpAddress, _RemotePortNumber);
            sMessages.Add("Client Socket Program - Server Connected ...");
        }


        ///         /// 傳送訊息至 socker server
        ///         /// 
訊息
        /// socker server 回傳結果
        public string Send(string inMessage)
        {
            try
            {
                //取得用來傳送訊息至 socket server 的 stream 物件
                NetworkStream serverStream = _TcpClient.GetStream();

                //將資料轉為 byte[]
                byte[] outStream = System.Text.Encoding.UTF8.GetBytes(inMessage);

                //將資料寫入 stream object (表示傳送資料至 socket server)
                serverStream.Write(outStream, 0, outStream.Length);
                serverStream.Flush();

                //讀取 socket server 回傳值並轉為 string
                byte[] inStream = new byte[10025];
                serverStream.Read(inStream, 0, (int)_TcpClient.ReceiveBufferSize);
                string returndata = System.Text.Encoding.UTF8.GetString(inStream);

                sMessages.Add("Data from Server : " + returndata);
                return returndata;
            }
            catch (Exception exp)
            {
                sMessages.Add(exp.ToString());
                return exp.ToString();
            }
        }

        #endregion
    }
}