• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            興海北路

            ---男兒仗劍自橫行
            <2025年7月>
            293012345
            6789101112
            13141516171819
            20212223242526
            272829303112
            3456789

            統計

            • 隨筆 - 85
            • 文章 - 0
            • 評論 - 17
            • 引用 - 0

            常用鏈接

            留言簿(6)

            隨筆分類

            隨筆檔案

            收藏夾

            全是知識啊

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            Linux軟件下載源碼編程文章資料周立發服務器源代碼如下:

            服務器源代碼如下:

            #include <stdarg.h>
            #include <errno.h>
            #include <stdio.h>
            #include <fcntl.h>
            #include <unistd.h>
            #include <string.h>
            #include <time.h>
            #include <sys/types.h>
            #include <sys/stat.h>
            #include <dirent.h>
            #include <errno.h>
            #include <netinet/in.h>
            #include <sys/socket.h>
            #include <resolv.h>
            #include <arpa/inet.h>
            #include <stdlib.h>
            #include <signal.h>
            #include <getopt.h>

            #define DEFAULTIP "127.0.0.1"
            #define DEFAULTPORT "80"
            #define DEFAULTBACK "10"
            #define DEFAULTDIR "/home"
            #define DEFAULTLOG "/tmp/das-server.log"

            void prterrmsg(char *msg);
            #define prterrmsg(msg)        { perror(msg); abort(); }
            void wrterrmsg(char *msg);
            #define wrterrmsg(msg)        { fputs(msg, logfp); fputs(strerror(errno), logfp);fflush(logfp); abort(); }

            void prtinfomsg(char *msg);
            #define prtinfomsg(msg)        { fputs(msg, stdout);  }
            void wrtinfomsg(char *msg);
            #define wrtinfomsg(msg)        {  fputs(msg, logfp); fflush(logfp);}

            #define MAXBUF        1024

            char buffer[MAXBUF + 1];
            char *host = 0;
            char *port = 0;
            char *back = 0;
            char *dirroot = 0;
            char *logdir = 0;
            unsigned char daemon_y_n = 0;
            FILE *logfp;

            #define MAXPATH        150

            /*----------------------------------------
             *--- dir_up - 查找dirpath所指目錄的上一級目錄
             *----------------------------------------
             */
            char *dir_up(char *dirpath)
            {
                static char Path[MAXPATH];
                int len;

                strcpy(Path, dirpath);
                len = strlen(Path);
                if (len > 1 && Path[len - 1] == '/')
                    len--;
                while (Path[len - 1] != '/' && len > 1)
                    len--;
                Path[len] = 0;
                return Path;
            }

            /*------------------------------------------------------
             *--- AllocateMemory - 分配空間并把d所指的內容復制
             *------------------------------------------------------
             */
            void AllocateMemory(char **s, int l, char *d)
            {
                *s = malloc(l + 1);
                bzero(*s, l + 1);
                memcpy(*s, d, l);
            }
            /************關于本文檔********************************************
            *filename: das-server.c
            *purpose: 這是在Linux下用C語言寫的目錄訪問服務器,支持目錄瀏覽和文件下載
            *wrote by: zhoulifa(zhoulifa@163.com) 周立發(http://zhoulifa.bokee.com)
            Linux愛好者 Linux知識傳播者 SOHO族 開發者 最擅長C語言
            *date time:2007-01-26 19:32
            *Note: 任何人可以任意復制代碼并運用這些文檔,當然包括你的商業用途
            * 但請遵循GPL
            *Thanks to: Google.com
            *Hope:希望越來越多的人貢獻自己的力量,為科學技術發展出力
            * 科技站在巨人的肩膀上進步更快!感謝有開源前輩的貢獻!
            *********************************************************************/
            /*------------------------------------------------------
             *--- GiveResponse - 把Path所指的內容發送到client_sock去
             *-------------------如果Path是一個目錄,則列出目錄內容
             *-------------------如果Path是一個文件,則下載文件
             *------------------------------------------------------
             */
            void GiveResponse(FILE * client_sock, char *Path)
            {
                struct dirent *dirent;
                struct stat info;
                char Filename[MAXPATH];
                DIR *dir;
                int fd, len, ret;
                char *p, *realPath, *realFilename, *nport;

                /* 獲得實際工作目錄或文件 */
                len = strlen(dirroot) + strlen(Path) + 1;
                realPath = malloc(len + 1);
                bzero(realPath, len + 1);
                sprintf(realPath, "%s/%s", dirroot, Path);

                /* 獲得實際工作端口 */
                len = strlen(port) + 1;
                nport = malloc(len + 1);
                bzero(nport, len + 1);
                sprintf(nport, ":%s", port);

                /* 獲得實際工作目錄或文件的信息以判斷是文件還是目錄 */
                if (stat(realPath, &info)) {
                    fprintf(client_sock,
                            "HTTP/1.1 200 OK\r\nServer: DAS by ZhouLifa\r\nConnection: close\r\n\r\n<html><head><title>%d - %s</title></head>"
                            "<body><font size=+4>Linux 下目錄訪問服務器</font><br><hr width=\"100%%\"><br><center>"
                            "<table border cols=3 width=\"100%%\">", errno,
                            strerror(errno));
                    fprintf(client_sock,
                            "</table><font color=\"CC0000\" size=+2>請向管理員咨詢為何出現如下錯誤提示:\n%s %s</font></body></html>",
                            Path, strerror(errno));
                    goto out;
                }
                /* 處理瀏覽文件請求,即下載文件 */
                if (S_ISREG(info.st_mode)) {
                    fd = open(realPath, O_RDONLY);
                    len = lseek(fd, 0, SEEK_END);
                    p = (char *) malloc(len + 1);
                    bzero(p, len + 1);
                    lseek(fd, 0, SEEK_SET);
                    ret = read(fd, p, len);
                    close(fd);
                    fprintf(client_sock,
                            "HTTP/1.1 200 OK\r\nServer: DAS by ZhouLifa\r\nConnection: keep-alive\r\nContent-type: application/*\r\nContent-Length:%d\r\n\r\n",
                            len);
                    fwrite(p, len, 1, client_sock);
                    free(p);
                } else if (S_ISDIR(info.st_mode)) {
                    /* 處理瀏覽目錄請求 */
                    dir = opendir(realPath);
                    fprintf(client_sock,
                            "HTTP/1.1 200 OK\r\nServer: DAS by ZhouLifa\r\nConnection: close\r\n\r\n<html><head><title>%s</title></head>"
                            "<body><font size=+4>Linux 下目錄訪問服務器</font><br><hr width=\"100%%\"><br><center>"
                            "<table border cols=3 width=\"100%%\">", Path);
                    fprintf(client_sock,
                            "<caption><font size=+3>目錄 %s</font></caption>\n",
                            Path);
                    fprintf(client_sock,
                            "<tr><td>名稱</td><td>大小</td><td>修改時間</td></tr>\n");
                    if (dir == 0) {
                        fprintf(client_sock,
                                "</table><font color=\"CC0000\" size=+2>%s</font></body></html>",
                                strerror(errno));
                        return;
                    }
                    /* 讀取目錄里的所有內容 */
                    while ((dirent = readdir(dir)) != 0) {
                        if (strcmp(Path, "/") == 0)
                            sprintf(Filename, "/%s", dirent->d_name);
                        else
                            sprintf(Filename, "%s/%s", Path, dirent->d_name);
                        fprintf(client_sock, "<tr>");
                        len = strlen(dirroot) + strlen(Filename) + 1;
                        realFilename = malloc(len + 1);
                        bzero(realFilename, len + 1);
                        sprintf(realFilename, "%s/%s", dirroot, Filename);
                        if (stat(realFilename, &info) == 0) {
                            if (strcmp(dirent->d_name, "..") == 0)
                                fprintf(client_sock,
                                        "<td><a href=\"http://%s%s%s\">(parent)</a></td>",
                                        host, atoi(port) == 80 ? "" : nport,
                                        dir_up(Path));
                            else
                                fprintf(client_sock,
                                        "<td><a href=\"http://%s%s%s\">%s</a></td>",
                                        host, atoi(port) == 80 ? "" : nport, Filename,
                                        dirent->d_name);
                            if (S_ISDIR(info.st_mode))
                                fprintf(client_sock, "<td>目錄</td>");
                            else if (S_ISREG(info.st_mode))
                                fprintf(client_sock, "<td>%d</td>", info.st_size);
                            else if (S_ISLNK(info.st_mode))
                                fprintf(client_sock, "<td>鏈接</td>");
                            else if (S_ISCHR(info.st_mode))
                                fprintf(client_sock, "<td>字符設備</td>");
                            else if (S_ISBLK(info.st_mode))
                                fprintf(client_sock, "<td>塊設備</td>");
                            else if (S_ISFIFO(info.st_mode))
                                fprintf(client_sock, "<td>FIFO</td>");
                            else if (S_ISSOCK(info.st_mode))
                                fprintf(client_sock, "<td>Socket</td>");
                            else
                                fprintf(client_sock, "<td>(未知)</td>");
                            fprintf(client_sock, "<td>%s</td>", ctime(&info.st_ctime));
                        }
                        fprintf(client_sock, "</tr>\n");
                        free(realFilename);
                    }
                    fprintf(client_sock, "</table></center></body></html>");
                } else {
                    /* 既非常規文件又非目錄,禁止訪問 */
                    fprintf(client_sock,
                            "HTTP/1.1 200 OK\r\nServer: DAS by ZhouLifa\r\nConnection: close\r\n\r\n<html><head><title>permission denied</title></head>"
                            "<body><font size=+4>Linux 下目錄訪問服務器</font><br><hr width=\"100%%\"><br><center>"
                            "<table border cols=3 width=\"100%%\">");
                    fprintf(client_sock,
                            "</table><font color=\"CC0000\" size=+2>你訪問的資源'%s'被禁止訪問,請聯系管理員解決!</font></body></html>",
                            Path);
                }
              out:
                free(realPath);
                free(nport);
            }

            /*------------------------------------------------------
             *--- getoption - 分析取出程序的參數
             *------------------------------------------------------
             */
            void getoption(int argc, char **argv)
            {
                int c, len;
                char *p = 0;

                opterr = 0;
                while (1) {
                    int option_index = 0;
                    static struct option long_options[] = {
                        {"host", 1, 0, 0},
                        {"port", 1, 0, 0},
                        {"back", 1, 0, 0},
                        {"dir", 1, 0, 0},
                        {"log", 1, 0, 0},
                        {"daemon", 0, 0, 0},
                        {0, 0, 0, 0}
                    };
                    /* 本程序支持如一些參數:
                     * --host IP地址 或者 -H IP地址
                     * --port 端口 或者 -P 端口
                     * --back 監聽數量 或者 -B 監聽數量
                     * --dir 網站根目錄 或者 -D 網站根目錄
                     * --log 日志存放路徑 或者 -L 日志存放路徑
                     * --daemon 使程序進入后臺運行模式
                     */
                    c = getopt_long(argc, argv, "H:P:B:D:L",
                                    long_options, &option_index);
                    if (c == -1 || c == '?')
                        break;

                    if(optarg)        len = strlen(optarg);
                    else        len = 0;

                    if ((!c && !(strcasecmp(long_options[option_index].name, "host")))
                        || c == 'H')
                        p = host = malloc(len + 1);
                    else if ((!c
                              &&
                              !(strcasecmp(long_options[option_index].name, "port")))
                             || c == 'P')
                        p = port = malloc(len + 1);
                    else if ((!c
                              &&
                              !(strcasecmp(long_options[option_index].name, "back")))
                             || c == 'B')
                        p = back = malloc(len + 1);
                    else if ((!c
                              && !(strcasecmp(long_options[option_index].name, "dir")))
                             || c == 'D')
                        p = dirroot = malloc(len + 1);
                    else if ((!c
                              && !(strcasecmp(long_options[option_index].name, "log")))
                             || c == 'L')
                        p = logdir = malloc(len + 1);
                    else if ((!c
                              &&
                              !(strcasecmp
                                (long_options[option_index].name, "daemon")))) {
                        daemon_y_n = 1;
                        continue;
                    }
                    else
                        break;
                    bzero(p, len + 1);
                    memcpy(p, optarg, len);
                }
            }

            int main(int argc, char **argv)
            {
                struct sockaddr_in addr;
                int sock_fd, addrlen;

                /* 獲得程序工作的參數,如 IP 、端口、監聽數、網頁根目錄、目錄存放位置等 */
                getoption(argc, argv);

                if (!host) {
                    addrlen = strlen(DEFAULTIP);
                    AllocateMemory(&host, addrlen, DEFAULTIP);
                }
                if (!port) {
                    addrlen = strlen(DEFAULTPORT);
                    AllocateMemory(&port, addrlen, DEFAULTPORT);
                }
                if (!back) {
                    addrlen = strlen(DEFAULTBACK);
                    AllocateMemory(&back, addrlen, DEFAULTBACK);
                }
                if (!dirroot) {
                    addrlen = strlen(DEFAULTDIR);
                    AllocateMemory(&dirroot, addrlen, DEFAULTDIR);
                }
                if (!logdir) {
                    addrlen = strlen(DEFAULTLOG);
                    AllocateMemory(&logdir, addrlen, DEFAULTLOG);
                }

                printf
                    ("host=%s port=%s back=%s dirroot=%s logdir=%s %s是后臺工作模式(進程ID:%d)\n",
                     host, port, back, dirroot, logdir, daemon_y_n?"":"不", getpid());

                /* fork() 兩次處于后臺工作模式下 */
                if (daemon_y_n) {
                    if (fork())
                        exit(0);
                    if (fork())
                        exit(0);
                    close(0), close(1), close(2);
                    logfp = fopen(logdir, "a+");
                    if (!logfp)
                        exit(0);
                }

                /* 處理子進程退出以免產生僵尸進程 */
                signal(SIGCHLD, SIG_IGN);

                /* 創建 socket */
                if ((sock_fd = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
                    if (!daemon_y_n) {
                        prterrmsg("socket()");
                    } else {
                        wrterrmsg("socket()");
                    }
                }

                /* 設置端口快速重用 */
                addrlen = 1;
                setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &addrlen,
                           sizeof(addrlen));

                addr.sin_family = AF_INET;
                addr.sin_port = htons(atoi(port));
                addr.sin_addr.s_addr = inet_addr(host);
                addrlen = sizeof(struct sockaddr_in);
                /* 綁定地址、端口等信息 */
                if (bind(sock_fd, (struct sockaddr *) &addr, addrlen) < 0) {
                    if (!daemon_y_n) {
                        prterrmsg("bind()");
                    } else {
                        wrterrmsg("bind()");
                    }
                }

                /* 開啟臨聽 */
                if (listen(sock_fd, atoi(back)) < 0) {
                    if (!daemon_y_n) {
                        prterrmsg("listen()");
                    } else {
                        wrterrmsg("listen()");
                    }
                }
                while (1) {
                    int len;
                    int new_fd;
                    addrlen = sizeof(struct sockaddr_in);
                    /* 接受新連接請求 */
                    new_fd = accept(sock_fd, (struct sockaddr *) &addr, &addrlen);
                    if (new_fd < 0) {
                        if (!daemon_y_n) {
                            prterrmsg("accept()");
                        } else {
                            wrterrmsg("accept()");
                        }
                        break;
                    }
                    bzero(buffer, MAXBUF + 1);
                    sprintf(buffer, "連接來自于: %s:%d\n",
                            inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
                    if (!daemon_y_n) {
                        prtinfomsg(buffer);
                    } else {
                        wrtinfomsg(buffer);
                    }
                    /* 產生一個子進程去處理請求,當前進程繼續等待新的連接到來 */
                    if (!fork()) {
                        bzero(buffer, MAXBUF + 1);
                        if ((len = recv(new_fd, buffer, MAXBUF, 0)) > 0) {
                            FILE *ClientFP = fdopen(new_fd, "w");
                            if (ClientFP == NULL) {
                                if (!daemon_y_n) {
                                    prterrmsg("fdopen()");
                                } else {
                                    prterrmsg("fdopen()");
                                }
                            } else {
                                char Req[MAXPATH + 1] = "";
                                sscanf(buffer, "GET %s HTTP", Req);
                                bzero(buffer, MAXBUF + 1);
                                sprintf(buffer, "請求取文件: \"%s\"\n", Req);
                                if (!daemon_y_n) {
                                    prtinfomsg(buffer);
                                } else {
                                    wrtinfomsg(buffer);
                                }
                                /* 處理用戶請求 */
                                GiveResponse(ClientFP, Req);
                                fclose(ClientFP);
                            }
                        }
                        exit(0);
                    }
                    close(new_fd);
                }
                close(sock_fd);
                return 0;
            }


            編譯程序用下列命令:
            gcc -Wall das-server.c -o das-server
            注:das即 Dictory Access Server

            以root用戶啟動服務程序用下列命令:
            ./das-server
            或以普通用戶啟動服務程序用下列命令:
            ./das-server --port 7838

            ./das-server -P 7838

            注:只有root用戶才有權限啟動1024以下的端口,所以如果想用默認的80端口就得用root來運行。

            如果要想讓程序在后臺自動運行,即處理精靈模式下工作,在命令后面加上--daemon參數即可。

            打開一個網絡瀏覽器輸入服務地址開始瀏覽,如下圖:


            下載文件如下圖:

            注:請不要下載較大的文件,比如文件大小超過10M的,因為程序是一次分配內存,會占用系統內存較大導致系統死掉!

            posted @ 2008-06-30 10:07 隨意門 閱讀(546) | 評論 (0)編輯 收藏
            HTTP協議的C語言編程實現實例

            大家都很熟悉HTTP協議的應用,因為每天都在網絡上瀏覽著不少東西,也都知道是HTTP協議是相當簡單的。每次用到FlashGet之類的下載軟件下載網頁,當用到那個“用FlashGet下載全部鏈接”時總覺得很神奇。
            后來想想,其實要實現這些下載功能也并不難,只要按照HTTP協議發送request,然后對接收到的數據進行分析,如果頁面上還有href之類的鏈接指向標志就可以進行深一層的下載了。HTTP協議目前用的最多的是1.1版本,要全面透徹地搞懂它就參考RFC2616文檔吧。
            下面是我用C語言編程寫的一個http下載程序,希望對大家有些啟發。源代碼如下:

            /******* http客戶端程序 httpclient.c ************/
            #include <stdio.h>
            #include <stdlib.h>
            #include <string.h>
            #include <sys/types.h>
            #include <sys/socket.h>
            #include <errno.h>
            #include <unistd.h>
            #include <netinet/in.h>
            #include <limits.h>
            #include <netdb.h>
            #include <arpa/inet.h>
            #include <ctype.h>

            //////////////////////////////httpclient.c 開始///////////////////////////////////////////

            /********************************************
            功能:搜索字符串右邊起的第一個匹配字符
            ********************************************/
            char * Rstrchr(char * s, char x)  {
              int i = strlen(s);
              if(!(*s))  return 0;
              while(s[i-1]) if(strchr(s + (i - 1), x))  return (s + (i - 1));  else i--;
              return 0;
            }

            /********************************************
            功能:把字符串轉換為全小寫
            ********************************************/
            void ToLowerCase(char * s)  {
              while(*s)  *s=tolower(*s++);
            }

            /**************************************************************
            功能:從字符串src中分析出網站地址和端口,并得到用戶要下載的文件
            ***************************************************************/
            void GetHost(char * src, char * web, char * file, int * port)  {
              char * pA;
              char * pB;
              memset(web, 0, sizeof(web));
              memset(file, 0, sizeof(file));
              *port = 0;
              if(!(*src))  return;
              pA = src;
              if(!strncmp(pA, "http://", strlen("http://")))  pA = src+strlen("http://");
              else if(!strncmp(pA, "https://", strlen("https://")))  pA = src+strlen("https://");
              pB = strchr(pA, '/');
              if(pB)  {
                memcpy(web, pA, strlen(pA) - strlen(pB));
                if(pB+1)  {
                  memcpy(file, pB + 1, strlen(pB) - 1);
                  file[strlen(pB) - 1] = 0;
                }
              }
              else  memcpy(web, pA, strlen(pA));
              if(pB)  web[strlen(pA) - strlen(pB)] = 0;
              else  web[strlen(pA)] = 0;
              pA = strchr(web, ':');
              if(pA)  *port = atoi(pA + 1);
              else *port = 80;
            }

            /*********************************************************************
            *filename: httpclient.c
            *purpose: HTTP協議客戶端程序,可以用來下載網頁
            *wrote by: zhoulifa(zhoulifa@163.com) 周立發(http://zhoulifa.bokee.com)
                       Linux愛好者 Linux知識傳播者 SOHO族 開發者 最擅長C語言
            *date time:2006-03-11 21:49:00
            *Note: 任何人可以任意復制代碼并運用這些代碼,當然包括你的商業用途
            *                         但請遵循GPL
            *********************************************************************/
            int main(int argc, char *argv[])
            {
              int sockfd;
              char buffer[1024];
              struct sockaddr_in server_addr;
              struct hostent *host;
              int portnumber,nbytes;
              char host_addr[256];
              char host_file[1024];
              char local_file[256];
              FILE * fp;
              char request[1024];
              int send, totalsend;
              int i;
              char * pt;

              if(argc!=2)
              {
                fprintf(stderr,"Usage:%s web-address\a\n",argv[0]);
                exit(1);
              }
              printf("parameter.1 is: %s\n", argv[1]);
              ToLowerCase(argv[1]);/*將參數轉換為全小寫*/
              printf("lowercase parameter.1 is: %s\n", argv[1]);

              GetHost(argv[1], host_addr, host_file, &portnumber);/*分析網址、端口、文件名等*/
              printf("webhost:%s\n", host_addr);
              printf("hostfile:%s\n", host_file);
              printf("portnumber:%d\n\n", portnumber);

              if((host=gethostbyname(host_addr))==NULL)/*取得主機IP地址*/
              {
                fprintf(stderr,"Gethostname error, %s\n", strerror(errno));
                exit(1);
              }

              /* 客戶程序開始建立 sockfd描述符 */
              if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)/*建立SOCKET連接*/
              {
                fprintf(stderr,"Socket Error:%s\a\n",strerror(errno));
                exit(1);
              }

              /* 客戶程序填充服務端的資料 */
              bzero(&server_addr,sizeof(server_addr));
              server_addr.sin_family=AF_INET;
              server_addr.sin_port=htons(portnumber);
              server_addr.sin_addr=*((struct in_addr *)host->h_addr);

              /* 客戶程序發起連接請求 */
              if(connect(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))==-1)/*連接網站*/
              {
                fprintf(stderr,"Connect Error:%s\a\n",strerror(errno));
                exit(1);
              }

              sprintf(request, "GET /%s HTTP/1.1\r\nAccept: */*\r\nAccept-Language: zh-cn\r\n\
            User-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)\r\n\
            Host: %s:%d\r\nConnection: Close\r\n\r\n", host_file, host_addr, portnumber);
              printf("%s", request);/*準備request,將要發送給主機*/

              /*取得真實的文件名*/
              if(host_file && *host_file)  pt = Rstrchr(host_file, '/');
              else pt = 0;

              memset(local_file, 0, sizeof(local_file));
              if(pt && *pt)  {
                if((pt + 1) && *(pt+1))  strcpy(local_file, pt + 1);
                else  memcpy(local_file, host_file, strlen(host_file) - 1);
              }
              else if(host_file && *host_file)  strcpy(local_file, host_file);
              else  strcpy(local_file, "index.html");
              printf("local filename to write:%s\n\n", local_file);

              /*發送http請求request*/
              send = 0;totalsend = 0;
              nbytes=strlen(request);
              while(totalsend < nbytes) {
                send = write(sockfd, request + totalsend, nbytes - totalsend);
                if(send==-1)  {printf("send error!%s\n", strerror(errno));exit(0);}
                totalsend+=send;
                printf("%d bytes send OK!\n", totalsend);
              }

              fp = fopen(local_file, "a");
              if(!fp)  {
                printf("create file error! %s\n", strerror(errno));
                return 0;
              }
              printf("\nThe following is the response header:\n");
              i=0;
              /* 連接成功了,接收http響應,response */
              while((nbytes=read(sockfd,buffer,1))==1)
              {
                if(i < 4)  {
                  if(buffer[0] == '\r' || buffer[0] == '\n')  i++;
                  else i = 0;
                  printf("%c", buffer[0]);/*把http頭信息打印在屏幕上*/
                }
                else  {
                  fwrite(buffer, 1, 1, fp);/*將http主體信息寫入文件*/
                  i++;
                  if(i%1024 == 0)  fflush(fp);/*每1K時存盤一次*/
                }
              }
              fclose(fp);
              /* 結束通訊 */
              close(sockfd);
              exit(0);
            }
            //////////////////////////////httpclient.c 結束///////////////////////////////////////////

            posted @ 2008-06-30 10:03 隨意門 閱讀(611) | 評論 (0)編輯 收藏
            csdn上ni_hao搜集的源代碼網站

            優秀網站源碼、編程源碼下載網站大集中
            1.51源碼:http://www.51aspx.com/

            2.源碼之家:http://www.codejia.com/

            3.源碼網:http://www.codepub.com/

            4.蝦客源碼:http://www.xkxz.com/

            5.多多源碼:http://www.morecode.net/

            6.洪越源代碼:http://www.softhy.net/

            7.鋒網源碼:http://www.fwvv.net/

            8.代碼愛好者:http://www.codefans.com/

            9.愛源碼:http://www.aiyuanma.com/

            10.酷源碼:http://www.kyuanma.com/

            11.搜源碼:http://www.soucode.com/

            12.拉基源碼:http://www.lajicode.com/

            13.源碼開發網:http://www.codedn.com/

            14.源碼天空:http://www.codesky.net/

            15.源碼吧:http://www.asp88.net/

            16.綠色源碼:http://code888.cn/

            17.9號源碼中心:http://www.9code.com/

            18.網馨源碼:http://www.asppsa.com/

            20.源碼天下:http://www.pccode.net/

            21.需要源碼:http://www.needcode.cn/

            22.華夏源碼:http://www.haocpu.com/

            23.天新網:http://codes.21tx.com/

            24.源碼網:http://www.yuanma5.com/

            25.無憂源碼:http://www.5uym.com/

            26.中國下載站:http://www.cnz.cc/

            27.資源吧:http://www.ziyuan8.com/

            28.啟明星源碼:http://www.codewww.com/

            29.我要源碼:http://www.xia51.com/

            30.清秋源碼:http://www.asp678.com/

            posted @ 2008-05-30 11:27 隨意門 閱讀(217) | 評論 (0)編輯 收藏
            精妙SQL語句

            下列語句部分是Mssql語句,不可以在access中使用。

            SQL分類: 
            DDL—數據定義語言(CREATE,ALTER,DROP,DECLARE) 
            DML—數據操縱語言(SELECT,DELETE,UPDATE,INSERT) 
            DCL—數據控制語言(GRANT,REVOKE,COMMIT,ROLLBACK)

            首先,簡要介紹基礎語句:
            1、說明:創建數據庫
            CREATE DATABASE database-name 
            2、說明:刪除數據庫
            drop database dbname
            3、說明:備份sql server
            --- 創建 備份數據的 device
            USE master
            EXEC sp_addumpdevice 'disk', 'testBack', 'c:\mssql7backup\MyNwind_1.dat'
            --- 開始 備份
            BACKUP DATABASE pubs TO testBack 
            4、說明:創建新表
            create table tabname(col1 type1 [not null] [primary key],col2 type2 [not null],..)
            根據已有的表創建新表: 
            A:create table tab_new like tab_old (使用舊表創建新表)
            B:create table tab_new as select col1,col2… from tab_old definition only
            5、說明:刪除新表drop table tabname 
            6、說明:增加一個列
            Alter table tabname add column col type
            注:列增加后將不能刪除。DB2中列加上后數據類型也不能改變,唯一能改變的是增加varchar類型的長度。
            7、說明:添加主鍵: Alter table tabname add primary key(col) 
            說明:刪除主鍵: Alter table tabname drop primary key(col) 
            8、說明:創建索引:create [unique] index idxname on tabname(col….) 
            刪除索引:drop index idxname
            注:索引是不可更改的,想更改必須刪除重新建。
            9、說明:創建視圖:create view viewname as select statement 
            刪除視圖:drop view viewname
            10、說明:幾個簡單的基本的sql語句
            選擇:select * from table1 where 范圍
            插入:insert into table1(field1,field2) values(value1,value2)
            刪除:delete from table1 where 范圍
            更新:update table1 set field1=value1 where 范圍
            查找:select * from table1 where field1 like ’%value1%’ ---like的語法很精妙,查資料!
            排序:select * from table1 order by field1,field2 [desc]
            總數:select count * as totalcount from table1
            求和:select sum(field1) as sumvalue from table1
            平均:select avg(field1) as avgvalue from table1
            最大:select max(field1) as maxvalue from table1
            最?。簊elect min(field1) as minvalue from table1
            11、說明:幾個高級查詢運算詞
            A: UNION 運算符 
            UNION 運算符通過組合其他兩個結果表(例如 TABLE1 和 TABLE2)并消去表中任何重復行而派生出一個結果表。當 ALL 隨  UNION 一起使用時(即 UNION ALL),不消除重復行。兩種情況下,派生表的每一行不是來自 TABLE1 就是來自 TABLE2。 
            B: EXCEPT 運算符 
            EXCEPT 運算符通過包括所有在 TABLE1 中但不在 TABLE2 中的行并消除所有重復行而派生出一個結果表。當 ALL 隨 EXCEPT 一起使用時 (EXCEPT ALL),不消除重復行。 
            C: INTERSECT 運算符
            INTERSECT 運算符通過只包括 TABLE1 和 TABLE2 中都有的行并消除所有重復行而派生出一個結果表。當 ALL 隨 INTERSECT 一起使用時 (INTERSECT ALL),不消除重復行。 
            注:使用運算詞的幾個查詢結果行必須是一致的。 
            12、說明:使用外連接 
            A、left outer join: 
            左外連接(左連接):結果集幾包括連接表的匹配行,也包括左連接表的所有行。 
            SQL: select a.a, a.b, a.c, b.c, b.d, b.f from a LEFT OUT JOIN b ON a.a = b.c
            B:right outer join: 
            右外連接(右連接):結果集既包括連接表的匹配連接行,也包括右連接表的所有行。 
            C:full outer join: 
            全外連接:不僅包括符號連接表的匹配行,還包括兩個連接表中的所有記錄。

            其次,大家來看一些不錯的sql語句
            1、說明:復制表(只復制結構,源表名:a 新表名:b) (Access可用)
            法一:select * into b from a where 1 <>1
            法二:select top 0 * into b from a

            2、說明:拷貝表(拷貝數據,源表名:a 目標表名:b) (Access可用)
            insert into b(a, b, c) select d,e,f from b;

            3、說明:跨數據庫之間表的拷貝(具體數據使用絕對路徑) (Access可用)
            insert into b(a, b, c) select d,e,f from b in ‘具體數據庫’ where 條件
            例子:..from b in '"&Server.MapPath(".")&"\data.mdb" &"' where..

            4、說明:子查詢(表名1:a 表名2:b)
            select a,b,c from a where a IN (select d from b ) 或者: select a,b,c from a where a IN (1,2,3)

            5、說明:顯示文章、提交人和最后回復時間
            select a.title,a.username,b.adddate from table a,(select max(adddate) adddate from table where table.title=a.title) b

            6、說明:外連接查詢(表名1:a 表名2:b)
            select a.a, a.b, a.c, b.c, b.d, b.f from a LEFT OUT JOIN b ON a.a = b.c

            7、說明:在線視圖查詢(表名1:a )
            select * from (SELECT a,b,c FROM a) T where t.a > 1;

            8、說明:between的用法,between限制查詢數據范圍時包括了邊界值,not between不包括
            select * from table1 where time between time1 and time2
            select a,b,c, from table1 where a not between 數值1 and 數值2

            9、說明:in 的使用方法
            select * from table1 where a [not] in (‘值1’,’值2’,’值4’,’值6’)

            10、說明:兩張關聯表,刪除主表中已經在副表中沒有的信息 
            delete from table1 where not exists ( select * from table2 where table1.field1=table2.field1 )

            11、說明:四表聯查問題:
            select * from a left inner join b on a.a=b.b right inner join c on a.a=c.c inner join d on a.a=d.d where .....

            12、說明:日程安排提前五分鐘提醒 
            SQL: select * from 日程安排 where datediff('minute',f開始時間,getdate())>5

            13、說明:一條sql 語句搞定數據庫分頁
            select top 10 b.* from (select top 20 主鍵字段,排序字段 from 表名 order by 排序字段 desc) a,表名 b where b.主鍵字段 = a.主鍵字段 order by a.排序字段

            14、說明:前10條記錄
            select top 10 * form table1 where 范圍

            15、說明:選擇在每一組b值相同的數據中對應的a最大的記錄的所有信息(類似這樣的用法可以用于論壇每月排行榜,每月熱銷產品分析,按科目成績排名,等等.)
            select a,b,c from tablename ta where a=(select max(a) from tablename tb where tb.b=ta.b)

            16、說明:包括所有在 TableA 中但不在 TableB和TableC 中的行并消除所有重復行而派生出一個結果表
            (select a from tableA ) except (select a from tableB) except (select a from tableC)

            17、說明:隨機取出10條數據
            select top 10 * from tablename order by newid()

            18、說明:隨機選擇記錄
            select newid()

            19、說明:刪除重復記錄
            Delete from tablename where id not in (select max(id) from tablename group by col1,col2,...)

            20、說明:列出數據庫里所有的表名
            select name from sysobjects where type='U' 

            21、說明:列出表里的所有的
            select name from syscolumns where id=object_id('TableName')

            22、說明:列示type、vender、pcs字段,以type字段排列,case可以方便地實現多重選擇,類似select 中的case。
            select type,sum(case vender when 'A' then pcs else 0 end),sum(case vender when 'C' then pcs else 0 end),sum(case vender when 'B' then pcs else 0 end) FROM tablename group by type
            顯示結果:
            type vender pcs
            電腦 A 1
            電腦 A 1
            光盤 B 2
            光盤 A 2
            手機 B 3
            手機 C 3

            23、說明:初始化表table1
            TRUNCATE TABLE table1

            24、說明:選擇從10到15的記錄
            select top 5 * from (select top 15 * from table order by id asc) table_別名 order by id desc
              
            隨機選擇數據庫記錄的方法(使用Randomize函數,通過SQL語句實現)
              對存儲在數據庫中的數據來說,隨機數特性能給出上面的效果,但它們可能太慢了些。你不能要求ASP“找個隨機數”然后打印出來。實際上常見的解決方案是建立如下所示的循環: 
            Randomize 
            RNumber = Int(Rnd*499) +1 
             
            While Not objRec.EOF 
            If objRec("ID") = RNumber THEN 
            ... 這里是執行腳本 ... 
            end if 
            objRec.MoveNext 
            Wend 
             
            這很容易理解。首先,你取出1到500范圍之內的一個隨機數(假設500就是數據庫內記錄的總數)。然后,你遍歷每一記錄來測試ID 的值、檢查其是 否匹配RNumber。滿足條件的話就執行由THEN 關鍵字開始的那一塊代碼。假如你的RNumber 等于495,那么要循環一遍數據庫花的時間可就 長了。雖然500這個數字看起來大了些,但相比更為穩固的企業解決方案這還是個小型數據庫了,后者通常在一個數據庫內就包含了成千上萬條記錄。這時候不就 死定了? 
              采用SQL,你就可以很快地找出準確的記錄并且打開一個只包含該記錄的recordset,如下所示: 
            Randomize 
            RNumber = Int(Rnd*499) + 1 
             
            SQL = "SELECT * FROM Customers WHERE ID = " & RNumber 
             
            set objRec = ObjConn.Execute(SQL) 
            Response.WriteRNumber & " = " & objRec("ID") & " " & objRec("c_email") 
             
              不必寫出RNumber 和ID,你只需要檢查匹配情況即可。只要你對以上代碼的工作滿意,你自可按需操作“隨機”記錄。Recordset沒有包含其他內容,因此你很快就能找到你需要的記錄這樣就大大降低了處理時間。 
            再談隨機數 
              現在你下定決心要榨干Random 函數的最后一滴油,那么你可能會一次取出多條隨機記錄或者想采用一定隨機范圍內的記錄。把上面的標準Random 示例擴展一下就可以用SQL應對上面兩種情況了。 
              為了取出幾條隨機選擇的記錄并存放在同一recordset內,你可以存儲三個隨機數,然后查詢數據庫獲得匹配這些數字的記錄: 
            SQL = "SELECT * FROM Customers WHERE ID = " & RNumber & " OR ID = " & RNumber2 & " OR ID = " & RNumber3 
             
              假如你想選出10條記錄(也許是每次頁面裝載時的10條鏈接的列表),你可以用BETWEEN 或者數學等式選出第一條記錄和適當數量的遞增記錄。這一操作可以通過好幾種方式來完成,但是 SELECT 語句只顯示一種可能(這里的ID 是自動生成的號碼): 
            SQL = "SELECT * FROM Customers WHERE ID BETWEEN " & RNumber & " AND " & RNumber & "+ 9" 

              注意:以上代碼的執行目的不是檢查數據庫內是否有9條并發記錄。

             
            隨機讀取若干條記錄,測試過
            Access語法:SELECT top 10 * From 表名 ORDER BY Rnd(id)
            Sql server:select top n * from 表名 order by newid()
            mysqlelect * From 表名 Order By rand() Limit n
            Access左連接語法(最近開發要用左連接,Access幫助什么都沒有,網上沒有Access的SQL說明,只有自己測試, 現在記下以備后查)
            語法elect table1.fd1,table1,fd2,table2.fd2 From table1 left join table2 on table1.fd1,table2.fd1 where ...
            使用SQL語句 用...代替過長的字符串顯示
            語法:
            SQL數據庫:select case when len(field)>10 then left(field,10)+'...' else field end as news_name,news_id from tablename
            Access數據庫:SELECT iif(len(field)>2,left(field,2)+'...',field) FROM tablename; 
             
            Conn.Execute說明
            Execute方法
              該方法用于執行SQL語句。根據SQL語句執行后是否返回記錄集,該方法的使用格式分為以下兩種:
                1.執行SQL查詢語句時,將返回查詢得到的記錄集。用法為:
                Set 對象變量名=連接對象.Execute("SQL 查詢語言")
               Execute方法調用后,會自動創建記錄集對象,并將查詢結果存儲在該記錄對象中,通過Set方法,將記錄集賦給指定的對象保存,以后對象變量就代表了該記錄集對象。

                2.執行SQL的操作性語言時,沒有記錄集的返回。此時用法為:
                連接對象.Execute "SQL 操作性語句" [, RecordAffected][, Option]
                  ·RecordAffected 為可選項,此出可放置一個變量,SQL語句執行后,所生效的記錄數會自動保存到該變量中。通過訪問該變量,就可知道SQL語句隊多少條記錄進行了操作。
                  ·Option 可選項,該參數的取值通常為adCMDText,它用于告訴ADO,應該將Execute方法之后的第一個字符解釋為命令文本。通過指定該參數,可使執行更高效。

            ·BeginTrans、RollbackTrans、CommitTrans方法

            posted @ 2008-05-21 15:20 隨意門 閱讀(250) | 評論 (0)編輯 收藏
            MySQL 5 C API 訪問數據庫例子程序

            /*****************************************************************
            以下是研究 mysql 5.0 得出的結果,描述并使用標準 c 演示了使用 MySQL
            C API 函數 簡單操作數據庫的流程;
            例子程序在 VC6 windows 2000 上調試通過
            *****************************************************************/

            #include <windows.h>
            #include <iostream>
            #include <mysql.h> //文件位于 MySQL 提供的 C API 目錄中
            using namespace std; 中國開源社區www.ossforge.com

            // linux 等系統中請加入 -lmysql
            #pragma comment( lib, "libmysql.lib")

            中國開源社區www.ossforge.com


            /*****************************************************************/
            ///name : main
            //function : 主測試函數
            //access : private
            //para :
            // 1. : int argc
            // : 系統參數個數
            // 2. : char * argv[]
            // : 參數數值
            //return : 返回給 startup 函數的退出參數
            //author : hzh
            //date : 2006-06-24
            /*****************************************************************/
            int main( int argc, char * argv[] )
            {
            MYSQL mydata; 中國開源社區www.openforge.cn

            //初始化數據結構
            if(mysql_init(&mydata) == NULL)
            {
            std::cout<<"init mysql data stauct fail"<<endl;
            return -1;
            }

            //連接數據庫
            if(argc == 1)
            {
            if(NULL == mysql_real_connect(&mydata,"127.0.0.1","root","mysql5",
            "hzhdb",MYSQL_PORT,NULL,0))
            {
            std::cout<<"connect database fail"<<endl<<mysql_error(&mydata)<<endl;
            return -1;
            }
            }else if(argc == 5)
            {
            if(NULL == mysql_real_connect(&mydata,argv[1],
            argv[2],argv[3],argv[4],MYSQL_PORT,NULL,0))
            {
            std::cout<<"connect database fail"<<endl<<mysql_error(&mydata)<<endl;
            return -1;
            }
            }
            else
            {
            std::cout<<"run parameter error"<<endl;
            return -1;
            } 中國開源社區www.openforge.cn

            std::string s_sql = "drop table hzhtest";
            if(mysql_query(&mydata,s_sql.c_str()) != 0)
            {
            //刪除表失敗
            mysql_close(&mydata);
            std::cout<<"drop table fail"<<endl<<mysql_error(&mydata)<<endl;
            }

            中國開源社區www.ossforge.com

            //創建數據表,字段 myid 設置了自增列屬性
            s_sql = "create table hzhtest(";
            s_sql = "myid integer not null auto_increment,";
            s_sql = "mytime datetime null,myname varchar(30),";
            s_sql = " primary key(myid))";
            if(mysql_query(&mydata,s_sql.c_str()) != 0)
            {
            //創建表失敗
            mysql_close(&mydata);
            std::cout<<"create table fail"<<endl
            <<mysql_error(&mydata)<<endl;
            return -1;
            } 中國開源社區www.openforge.cn

            //向表中插入數據
            for(int k = 1; k < 30; k)
            {
            s_sql = "insert into hzhtest(mytime,myname) values";
            s_sql = "('2006-06-";
            char buff[20];
            memset(buff,0,sizeof(buff));
            itoa(k,buff,10);
            s_sql = buff;

            中國開源社區www.ossforge.com

            s_sql = " ";

            中國開源社區www.openforge.cn

            int i = k % 3;
            memset(buff,0,sizeof(buff));
            itoa(i,buff,10);
            s_sql = buff;
            s_sql = ":01:01'"; 中國開源社區www.ossforge.com

            if(i == 0)
            {
            s_sql = ",NULL";
            }
            else
            {
            s_sql = ",'黃志輝";
            s_sql = buff;
            s_sql = "'";
            }
            s_sql = ")"; 中國開源社區www.openforge.cn

            if(mysql_query(&mydata,s_sql.c_str()) != 0)
            {
            //執行SQL語句出錯
            std::cout<<"execute insert syntax fail"<<
            endl<<mysql_error(&mydata)<<endl;
            mysql_close(&mydata) ;
            return -1;
            }
            }

            中國開源社區www.openforge.cn

            //查詢數據并顯示
            s_sql = "select myid,mytime,myname from hzhtest";
            if(mysql_query(&mydata,s_sql.c_str()) != 0)
            {
            //執行SQL語句出錯
            mysql_close(&mydata);
            std::cout<<"execute sql syntax fail"<<
            endl<<mysql_error(&mydata)<<endl;
            return -1;
            } 中國開源社區www.ossforge.com


            MYSQL_RES *result = mysql_store_result(&mydata);

            中國開源社區www.ossforge.com

            //取得查詢結果
            int rowcount = mysql_num_rows(result);
            //取得有效記錄數
            std::cout<<"exec sql: "<<s_sql.c_str()<<",row count: "<<rowcount<<endl;

            中國開源社區www.openforge.cn

            MYSQL_FIELD *fields = NULL;
            //取得各字段名
            for(int i = 0; fields = mysql_fetch_field(result); i)
            {
            std::cout<<fields->name<<"\t\t";
            }
            std::cout<<endl; 中國開源社區www.ossforge.com


            //依次讀取各條記錄
            MYSQL_ROW currrow = NULL;
            while((currrow = mysql_fetch_row(result)) != NULL)
            {
            //讀行的記錄
            for(int i = 0; i < mysql_num_fields(result); i)
            {
            std::cout<<(currrow[i] ? currrow[i] : "NULL")<<"\t";
            }
            std::cout<<endl;
            } 中國開源社區www.openforge.cn

            mysql_free_result(result) ;

            mysql_close(&mydata);

            system("pause"); 中國開源社區www.ossforge.com

            return 1;
            }

            posted @ 2008-05-19 10:42 隨意門 閱讀(239) | 評論 (0)編輯 收藏
            基于C API的MySQL數據庫多線程訪問方法

            摘要:目前,數據庫在各行各業中廣泛應用。在眾多商業數據庫軟件中,SQL SERVER 和ORACLE被較多的使用,因此這兩個數據庫軟件的價格也較昂貴。本文主要介紹MySQL數據庫在單線程或多線程程序環境下使用C API訪問MySQL數據庫方法,并給出了相應代碼和分析。該數據庫屬于開源數據庫,具有較高的成熟度,并且對于社區版本可以免費使用,因此對于需要使用 C API訪問數據庫的項目開發,可降低開發成本。
              關鍵詞:MySQL;C API;多線程
              中圖分類號:TP311文獻標識碼:A文章編號:1009-3044(2007)16-30904-02
              Based on C API MySQL Database Multi-threaded Access Methods
              YU Cheng-gong
              (Zhejiang Pharmaceutical College,Ningbo 315100,China)
              Abstract:Currently,the database in all walks of life were widely used.In many commercial database software,SQL Server and Oracle are used more and therefore their prices are more expensive. This paper describes the MySQL database in single-threaded or multi-threaded programming environment using C API access to the MySQL database, and gives the corresponding code and analysis. The database is open source database, with a higher maturity level, and the community version can be used for free. It satisfies the need to use the C API access to the database of project development, and reduces development costs.
              Key words:MySQL;C API;multi-threaded

              1 引言

              隨著社會信息化的深入,數據庫在社會各個領域被廣泛應用。在這些數據庫應用項目開發過程中,需要做兩方面的決策:1. 使用何種數據庫軟件;2. 采用何種方式訪問數據庫。數據庫軟件的選擇面比較寬,在目前眾多商業數據庫軟件中,SQL SERVER 和ORACLE被較多的使用,當然這兩個數據庫軟件的價格也較昂貴,本文選擇可免費使用的MySQL數據庫社區版本,MySQL庫屬于開源數據庫,具有較 高的成熟度和可靠性。數據庫的訪問方式有很多,可以使用ODBC、DAO、ADO等方法,這些方法簡單直接但是效率不高,不適合大型復雜的系統使用,例如 網絡游戲的數據庫系統開發需要考慮同時大量的數據庫訪問,因此訪問的效率非常重要。基于C程序語言的高效率,使用C API訪問數據庫可以提高數據庫的訪問效率?;谝陨蟽牲c,本文將介紹基于C API的MySQL數據庫訪問方法,給出在單線程和多線程程序環境下的具體代碼和分析。

              2 建表

              為了方便說明數據庫的訪問,先建立一個數據庫表TestTable,可以使用SQL語句創建該表,也可以使用MySQL提供的圖形界面來創建。數據庫表中字段如下:
              該數據庫表使用最常見的用戶名和密碼作為字段,本文將通過該表來實現不同程序環境下基于C API的數據庫的訪問方法。

              3 單線程程序的數據庫訪問

              單線程應用程序訪問MySQL數據庫相對簡單,其過程包含以下幾步:
              (1)初始化MySQL庫
              (2)初始化數據庫連接句柄
              (3)連接數據庫
              (4)通過SQL語句操作數據庫并處理相應數據
              (5)關閉數據庫連接
              (6)結束MySQL庫
              通過這五個步驟即可實現數據庫的訪問,具體代碼和分析如下:
              //在main主函數中添加代碼
              //1.定義訪問數據庫所需變量
              MYSQL * myData;
              MYSQL_RES * res;
              MYSQL_ROW row;
              //2. 初始化MySQL庫和數據庫連接句柄
              myData = mysql_init((MYSQL*) 0);
              //3. 連接數據庫,MYSQL_IP和MYSQL_PORT表示數據庫的IP和端口
              // MYSQL_ACCOUNT, MYSQL_PASSWORD表示數據庫連接的帳號和密碼
              //MYSQL_DBNAME表示所要訪問的數據庫名
              mysql_real_connect( myData, MYSQL_IP, MYSQL_ACCOUNT, MYSQL_PASSWORD, MYSQL_DBNAME, MYSQL_PORT,NULL, 0 )
              //4. 通過SQL語句操作數據庫并處理相應數據
              //4.1新建用戶名為abcdef,密碼為123456的記錄
              mysql_query(myData, "insert into TestTable value(‘abcdef’,’ 123456’)");
              //4.2顯示所有記錄
              //查詢所有記錄
              mysql_query(myData, "select * from TestTable");
              //將查詢結果保存到res中
              res = mysql_store_result( myData ) ;
              //逐條顯示記錄
              Int j = 0;
              while ( row = mysql_fetch_row( res ) ) {//獲取一條記錄
              j = mysql_num_fields( res ) ;//獲取每條記錄的字段數
            for ( k = 0 ; k < j ; k++ )
              printf( “%s”, row[k] ) ;
              printf( “\n”) ;
              }
              //釋放res
              mysql_free_result( res ) ;
              //5. 關閉數據庫連接
              mysql_close( myData );
              //6. 結束MySQL庫
              mysql_library_end();
              關于代碼的幾點說明:
              (1)定義變量中的三個數據結構為訪問MySQL所需,MYSQL結構表示一個數據庫連接的句柄,其中包含了數據庫連接所需的參數,MYSQL_RES結構表示數據庫訪問中一個查詢的返回結果,MYSQL_ROW結構表示返回結構中的一條記錄;
              (2)獲取查詢結果res并處理完畢,必須釋放res,否則會造成內存泄露
              (3)在單線程時,步驟初始化MySQL庫和數據庫連接句柄可合并, 由mysql_init()來處理。該函數會自動調用函數mysql_library_init()來初始化MySQL庫,同時初始化連接句柄。

              4 多線程環境下的數據庫訪問

              多線程環境下的數據庫訪問需要保證線程安全。Windows版本的MySQL C API函數都是線程安全的,除了mysql_library_init(),而我們剛才的代碼中使用的mysql_init()函數會自動調用函數 mysql_library_init()來初始化MySQL庫,因此在多線程環境下,需要不同的初始化代碼和清理代碼。具體過程如下:
              (1)在主函數中調用mysql_library_init()來初始化MySQL庫;
              (2)啟動各數據庫訪問線程
              (3)主函數等待各個線程的結束
              (4)調用mysql_library_end ()清理MySQL庫。
              其中數據庫訪問線程的代碼和單線程數據庫訪問代碼類似,但是需要如下變化:
              (1)單線程中的第2步初始化MySQL庫和數據庫連接句柄,不能再使用mysql_init(),代碼應作如下修改:
              //初始化線程
              my_init();
              mysql_thread_init();
              //初始化myData
              myData = malloc(sizeof(MYSQL));
              memset(&myData, 0, sizeof(MYSQL))
              (2)上述初始化myData,只是將myData所有成員設為0,如果有需要可以根據具體情況設置該結構成員的值,例myData->reconnect= 1,其作用是設置數據庫連接屬性為重連接,即當數據庫連接斷開時,自動重新連接;
              (3)單線程中的第6步不在需要,改為結束線程的清理工作,即調用mysql_thread_end()函數。

              5 總結

              綜上所述,使用C API訪問MySQL數據庫在不同線程環境下的區別主要在于初始化和訪問結束后清理代碼,也就是說除了初始化和清理代碼,MySQL提供給我們的C API函數都是線程安全的。最后需要有一點說明,使用C API訪問數據庫可以提高數據庫的訪問效率,但并不是所有的數據庫項目都適合這種方式,該方式適合需要大量實時并發處理的數據庫項目,例如網絡游戲的數據 庫項目,對于有此需求的數據庫項目可參考本文。

              參考文獻:
              [1]MySQL AB,MySQL 5.0 Reference Manual.

              注:“本文中所涉及到的圖表、公式注解等形式請以PDF格式閱讀原文。”

            posted @ 2008-04-22 16:35 隨意門 閱讀(5043) | 評論 (1)編輯 收藏
            如何開啟系統端口

            如何開啟系統端口

            --------------------------------------------------------------------------------
            win本身大部分的端口應該都是開的吧,只能是關哪個端口。

            試試這片文章:
            查看端口
            在Windows 2000/XP/Server 2003中要查看端口,可以使用Netstat命令:

            依次點擊“開始→運行”,鍵入“cmd”并回車,打開命令提示符窗口。在命令提示符狀態下鍵入“netstat -a -n”,按下回車鍵后就可以看到以數字形式顯示的TCP和UDP連接的端口號及狀態。

            小知識:Netstat命令用法
            命令格式:Netstat -a -e -n -o -s

            -a 表示顯示所有活動的TCP連接以及計算機監聽的TCP和UDP端口。

            -e 表示顯示以太網發送和接收的字節數、數據包數等。

            -n 表示只以數字形式顯示所有活動的TCP連接的地址和端口號。

            -o 表示顯示活動的TCP連接并包括每個連接的進程ID(PID)。

            -s 表示按協議顯示各種連接的統計信息,包括端口號。

            關閉/開啟端口
            在介紹各種端口的作用前,這里先介紹一下在Windows中如何關閉/打開端口,因為默認的情況下,有很多不安全的或沒有什么用的端口是開啟的, 比如Telnet服務的23端口、FTP服務的21端口、SMTP服務的25端口、RPC服務的135端口等等。為了保證系統的安全性,我們可以通過下面 的方法來關閉/開啟端口。

            關閉端口
            比如在Windows 2000/XP中關閉SMTP服務的25端口,可以這樣做:首先打開“控制面板”,雙擊“管理工具”,再雙擊“服務”。接著在打開的服務窗口中找到并雙擊 “Simple Mail Transfer Protocol (SMTP)”服務,單擊“停止”按鈕來停止該服務,然后在“啟動類型”中選擇“已禁用”,最后單擊“確定”按鈕即可。這樣,關閉了SMTP服務就相當于 關閉了對應的端口。

            開啟端口
            如果要開啟該端口只要先在“啟動類型”選擇“自動”,單擊“確定”按鈕,再打開該服務,在“服務狀態”中單擊“啟動”按鈕即可啟用該端口,最后,單擊“確定”按鈕即可。



            21端口:21端口主要用于FTP(File Transfer Protocol,文件傳輸協議)服務。 23端口:23端口主要用于Telnet(遠程登錄)服務,是Internet上普遍采用的登錄和仿真程序。 25端口:25端口為SMTP(Simple Mail Transfer Protocol,簡單郵件傳輸協議)服務器所開放,主要用于發送郵件,如今絕大多數郵件服務器都使用該協議。 53端口:53端口為DNS(Domain Name Server,域名服務器)服務器所開放,主要用于域名解析,DNS服務在NT系統中使用的最為廣泛。 67、68端口:67、68端口分別是為Bootp服務的Bootstrap Protocol Server(引導程序協議服務端)和Bootstrap Protocol Client(引導程序協議客戶端)開放的端口。 69端口:TFTP是Cisco公司開發的一個簡單文件傳輸協議,類似于FTP。 79端口:79端口是為Finger服務開放的,主要用于查詢遠程主機在線用戶、操作系統類型以及是否緩沖區溢出等用戶的詳細信息。 80端口:80端口是為HTTP(HyperText Transport Protocol,超文本傳輸協議)開放的,這是上網沖浪使用最多的協議,主要用于在WWW(World Wide Web,萬維網)服務上傳輸信息的協議。 99端口:99端口是用于一個名為“Metagram Relay”(亞對策延時)的服務,該服務比較少見,一般是用不到的。 109、110端口:109端口是為POP2(Post Office Protocol Version 2,郵局協議2)服務開放的,110端口是為POP3(郵件協議3)服務開放的,POP2、POP3都是主要用于接收郵件的。 111端口:111端口是SUN公司的RPC(Remote Procedure Call,遠程過程調用)服務所開放的端口,主要用于分布式系統中不同計算機的內部進程通信,RPC在多種網絡服務中都是很重要的組件。 113端口:113端口主要用于Windows的“Authentication Service”(驗證服務)。 119端口:119端口是為“Network News Transfer Protocol”(網絡新聞組傳輸協議,簡稱NNTP)開放的。 135端口:135端口主要用于使用RPC(Remote Procedure Call,遠程過程調用)協議并提供DCOM(分布式組件對象模型)服務。 137端口:137端口主要用于“NetBIOS Name Service”(NetBIOS名稱服務)。 139端口:139端口是為“NetBIOS Session Service”提供的,主要用于提供Windows文件和打印機共享以及Unix中的Samba服務。 143端口:143端口主要是用于“Internet Message Access Protocol”v2(Internet消息訪問協議,簡稱IMAP)。 161端口:161端口是用于“Simple Network Management Protocol”(簡單網絡管理協議,簡稱SNMP)。 443端口:43端口即網頁瀏覽端口,主要是用于HTTPS服務,是提供加密和通過安全端口傳輸的另一種HTTP。 554端口:554端口默認情況下用于“Real Time Streaming Protocol”(實時流協議,簡稱RTSP)。 1024端口:1024端口一般不固定分配給某個服務,在英文中的解釋是“Reserved”(保留)。 1080端口:1080端口是Socks代理服務使用的端口,大家平時上網使用的WWW服務使用的是HTTP協議的代理服務。 1755端口:1755端口默認情況下用于“Microsoft Media Server”(微軟媒體服務器,簡稱MMS)。 4000端口:4000端口是用于大家經常使用的QQ聊天工具的,再細說就是為QQ客戶端開放的端口,QQ服務端使用的端口是8000。 5554端口:在今年4月30日就報道出現了一種針對微軟lsass服務的新蠕蟲病毒——震蕩波(Worm.Sasser),該病毒可以利用TCP 5554端口開啟一個FTP服務,主要被用于病毒的傳播。 5632端口:5632端口是被大家所熟悉的遠程控制軟件pcAnywhere所開啟的端口。 8080端口:8080端口同80端口,是被用于WWW代理服務的,可以實現網頁端口概念 在網絡技術中,端口(Port)大致有兩種意思:一是物理意義上的端口,比如,ADSL Modem、集線器、交換機、路由器用于連接其他網絡設備的接口,如RJ-45端口、SC端口等等。二是邏輯意義上的端口,一般是指TCP/IP協議中的 端口,端口號的范圍從0到65535,比如用于瀏覽網頁服務的80端口,用于FTP服務的21端口等等。我們這里將要介紹的就是邏輯意義上的端口。 端口分類 邏輯意義上的端口有多種分類標準,下面將介紹兩種常見的分類: 1. 按端口號分布劃分 (1)知名端口(Well-Known Ports) 知名端口即眾所周知的端口號,范圍從0到1023,這些端口號一般固定分配給一些服務。比如21端口分配給FTP服務,25端口分配給SMTP(簡單郵件 傳輸協議)服務,80端口分配給HTTP服務,135端口分配給RPC(遠程過程調用)服務等等。 (2)動態端口(Dynamic Ports) 動態端口的范圍從1024到65535,這些端口號一般不固定分配給某個服務,也就是說許多服務都可以使用這些端口。只要運行的程序向系統提出訪問網絡的 申請,那么系統就可以從這些端口號中分配一個供該程序使用。比如1024端口就是分配給第一個向系統發出申請的程序。在關閉程序進程后,就會釋放所占用的 端口號。 不過,動態端口也常常被病毒木馬程序所利用,如冰河默認連接端口是7626、WAY 2.4是8011、Netspy 3.0是7306、YAI病毒是1024等等。 2. 按協議類型劃分 按協議類型劃分,可以分為TCP、UDP、IP和ICMP(Internet控制消息協議)等端口。下面主要介紹TCP和UDP端口: (1)TCP端口 TCP端口,即傳輸控制協議端口,需要在客戶端和服務器之間建立連接,這樣可以提供可靠的數據傳輸。常見的包括FTP服務的21端口,Telnet服務的 23端口,SMTP服務的25端口,以及HTTP服務的80端口等等。 (2)UDP端口 UDP端口,即用戶數據包協議端口,無需在客戶端和服務器之間建立連接,安全性得不到保障。常見的有DNS服務的53端口,SNMP(簡單網絡管理協議) 服務的161端口,QQ使用的8000和4000端口等等。查看端口 在Windows 2000/XP/Server 2003中要查看端口,可以使用Netstat命令: 依次點擊“開始→運行”,鍵入“cmd”并回車,打開命令提示符窗口。在命令提示符狀態下鍵入“netstat -a -n”,按下回車鍵后就可以看到以數字形式顯示的TCP和UDP連接的端口號及狀態(如圖)。 小知識:Netstat命令用法 命令格式:Netstat -a -e -n -o -s -a 表示顯示所有活動的TCP連接以及計算機監聽的TCP和UDP端口。 -e 表示顯示以太網發送和接收的字節數、數據包數等。 -n 表示只以數字形式顯示所有活動的TCP連接的地址和端口號。 -o 表示顯示活動的TCP連接并包括每個連接的進程ID(PID)。 -s 表示按協議顯示各種連接的統計信息,包括端口號。 關閉/開啟端口 在介紹各種端口的作用前,這里先介紹一下在Windows中如何關閉/打開端口,因為默認的情況下,有很多不安全的或沒有什么用的端口是開啟的,比如 Telnet服務的23端口、FTP服務的21端口、SMTP服務的25端口、RPC服務的135端口等等。為了保證系統的安全性,我們可以通過下面的方 法來關閉/開啟端口。 關閉端口 比如在Windows 2000/XP中關閉SMTP服務的25端口,可以這樣做:首先打開“控制面板”,雙擊“管理工具”,再雙擊“服務”。接著在打開的服務窗口中找到并雙擊 “Simple Mail Transfer Protocol (SMTP)”服務,單擊“停止”按鈕來停止該服務,然后在“啟動類型”中選擇“已禁用”,最后單擊“確定”按鈕即可。這樣,關閉了SMTP服務就相當于 關閉了對應的端口。 開啟端口 如果要開啟該端口只要先在“啟動類型”選擇“自動”,單擊“確定”按鈕,再打開該服務,在“服務狀態”中單擊“啟動”按鈕即可啟用該端口,最后,單擊“確 定”按鈕即可。 提示:在Windows 98中沒有“服務”選項,你可以使用防火墻的規則設置功能來關閉/開啟端口。 79端口 端口說明:79端口是為Finger服務開放的,主要用于查詢遠程主機在線用戶、操作系統類型以及是否緩沖區溢出等用戶的詳細信息。比如要顯示遠程計算機www.abc.com上的user01用戶的信息,可以在命令行中鍵入“finger user01@www.abc.com” 即可。 端口漏洞:一般黑客要攻擊對方的計算機,都是通過相應的端口掃描工具來獲得相關信息,比如使用“流光”就可以利用79端口來掃描遠程計算機操作系統版本, 獲得用戶信息,還能探測已知的緩沖區溢出錯誤。這樣,就容易遭遇到黑客的攻擊。而且,79端口還被Firehotcker木馬作為默認的端口。 操作建議:建議關閉該端口。 80端口 端口說明:80端口是為HTTP(HyperText Transport Protocol,超文本傳輸協議)開放的,這是上網沖浪使用最多的協議,主要用于在WWW(World Wide Web,萬維網)服務上傳輸信息的協議。我們可以通過HTTP地址加“:80”(即常說的“網址”)來訪問網站的,比如http://www.cce.com.cn:80, 因為瀏覽網頁服務默認的端口號是80,所以只要輸入網址,不用輸入“:80”。 端口漏洞:有些木馬程序可以利用80端口來攻擊計算機的,比如Executor、RingZero等。 操作建議:為了能正常上網沖浪,我們必須開啟80端口。 109與110端口 端口說明:109端口是為POP2(Post Office Protocol Version 2,郵局協議2)服務開放的,110端口是為POP3(郵件協議3)服務開放的,POP2、POP3都是主要用于接收郵件的,目前POP3使用的比較多, 許多服務器都同時支持POP2和POP3。客戶端可以使用POP3協議來訪問服務端的郵件服務,如今ISP的絕大多數郵件服務器都是使用該協議。在使用電 子郵件客戶端程序的時候,會要求輸入POP3服務器地址,默認情況下使用的就是110端口(如圖)。 端口漏洞:POP2、POP3在提供郵件接收服務的同時,也出現了不少的漏洞。單單POP3服務在用戶名和密碼交換緩沖區溢出的漏洞就不少于20個,比如 WebEasyMail POP3 Server合法用戶名信息泄露漏洞,通過該漏洞遠程攻擊者可以驗證用戶賬戶的存在。另外,110端口也被ProMail trojan等木馬程序所利用,通過110端口可以竊取POP賬號用戶名和密碼。 操作建議:如果是執行郵件服務器,可以打開該端口。 135端口 端口說明:135端口主要用于使用RPC(Remote Procedure Call,遠程過程調用)協議并提供DCOM(分布式組件對象模型)服務,通過RPC可以保證在一臺計算機上運行的程序可以順利地執行遠程計算機上的代 碼;使用DCOM可以通過網絡直接進行通信,能夠跨包括HTTP協議在內的多種網絡傳輸。 端口漏洞:相信去年很多Windows 2000和Windows XP用戶都中了“沖擊波”病毒,該病毒就是利用RPC漏洞來攻擊計算機的。RPC本身在處理通過TCP/IP的消息交換部分有一個漏洞,該漏洞是由于錯誤 地處理格式不正確的消息造成的。該漏洞會影響到RPC與DCOM之間的一個接口,該接口偵聽的端口就是135。 操作建議:為了避免“沖擊波”病毒的攻擊,建議關閉該端口 137端口 端口說明:137端口主要用于“NetBIOS Name Service”(NetBIOS名稱服務),屬于UDP端口,使用者只需要向局域網或互聯網上的某臺計算機的137端口發送一個請求,就可以獲取該計算 機的名稱、注冊用戶名,以及是否安裝主域控制器、IIS是否正在運行等信息。 端口漏洞:因為是UDP端口,對于攻擊者來說,通過發送請求很容易就獲取目標計算機的相關信息,有些信息是直接可以被利用,并分析漏洞的,比如IIS服 務。另外,通過捕獲正在利用137端口進行通信的信息包,還可能得到目標計算機的啟動和關閉的時間,這樣就可以利用專門的工具來攻擊。 操作建議:建議關閉該端口。 139端口 端口說明:139端口是為“NetBIOS Session Service”提供的,主要用于提供Windows文件和打印機共享以及Unix中的Samba服務。在Windows中要在局域網中進行文件的共享, 必須使用該服務。比如在Windows 98中,可以打開“控制面板”,雙擊“網絡”圖標,在“配置”選項卡中單擊“文件及打印共享”按鈕選中相應的設置就可以安裝啟用該服務;在Windows 2000/XP中,可以打開“控制面板”,雙擊“網絡連接”圖標,打開本地連接屬性;接著,在屬性窗口的“常規”選項卡中選擇“Internet協議 (TCP/IP)”,單擊“屬性”按鈕;然后在打開的窗口中,單擊“高級”按鈕;在“高級TCP/IP設置”窗口中選擇“WINS”選項卡,在 “NetBIOS設置”區域中啟用TCP/IP上的NetBIOS。 端口漏洞:開啟139端口雖然可以提供共享服務,但是常常被攻擊者所利用進行攻擊,比如使用流光、SuperScan等端口掃描工具,可以掃描目標計算機 的139端口,如果發現有漏洞,可以試圖獲取用戶名和密碼,這是非常危險的

            posted @ 2008-04-18 15:10 隨意門 閱讀(1522) | 評論 (0)編輯 收藏
            MySQL:無法遠程登入MySQL Server解決(摘合)

            MySQL:無法遠程登入MySQL Server

            嘗試用MySQL Adminstrator GUI Tool登入MySQL Server,Server卻回復錯誤訊息:Host '60-248-32-13.HINET-IP.hinet.net' is not allowed to connect to this
            MySQL server

            這個是因為權限的問題,處理方式如下:
            shell>mysql --user=root -p
            輸入密碼
            mysql>use mysql
            mysql>GRANT SELECT,INSERT,UPDATE,DELETE ON [db_name].* TO [username]@[ipadd] identified by '[password]';

            [username]:遠程登入的使用者代碼
            [db_name]:表示欲開放給使用者的數據庫稱
            [password]:遠程登入的使用者密碼
            [ipadd]:IP地址或者IP反查后的DNS Name,此例的內容需填入'60-248-32-13.HINET-IP.hinet.net' ,包函上引號(')

            (其實就是在遠端服務器上執行,地址填寫本地主機的ip地址。)

            如果希望開放所有權限的話請執行:
            mysql>update user set select_priv='Y' , Insert_priv='Y', Update_priv='Y', delete_priv='Y', Create_priv='Y', Drop_priv='Y',Reload_priv='Y', shutdown_priv='Y', Process_priv='Y', File_priv='Y', Grant_priv='Y', references_priv='Y',Index_priv='Y', Alter_priv='Y', Show_db_priv='Y', Super_priv='Y',Create_tmp_table_priv='Y',Lock_tables_priv='Y', Execute_priv='Y',Repl_slave_priv='Y',Repl_client_priv='Y' where user='[username]';

             

             

            如何解決客戶端與服務器端的連接(mysql) :xxx.xxx.xxx.xxx is not allowed to connect to this mysql serv

            這兩天搞MySQL,遇到一些問題,怕忘掉,放上來,留著備用

            這個方法是在google上搜出來的,不過他是轉自CSDN,^_^

            1、進入mysql,創建一個新用戶xuys:
             格式:grant 權限 on 數據庫名.表名 用戶@登錄主機 identified by "用戶密碼";
             grant select,update,insert,delete on *.* to xuys@192.168.88.234 identified by "xuys1234";
               查看結果,執行:
               use mysql;
               select host,user,password from user;
               可以看到在user表中已有剛才創建的xuys用戶。host字段表示登錄的主機,其值可以用IP,也可用主機名,
               將host字段的值改為%就表示在任何客戶端機器上能以xuys用戶登錄到mysql服務器,建議在開發時設為%。
               update user set host = '%' where user = 'xuys';
            2、 ./mysqladmin -uroot -p21century reload
             ./mysqladmin -uroot -p21century shutdown
            3、./mysqld_safe --user-root &
            記住:對授權表的任何修改都需要重新reload,即執行第3步。

            如果經過以上3個步驟還是無法從客戶端連接,請執行以下操作,在mysql數據庫的db表中插入一條記錄:
            use mysql;
            insert into db values('192.168.88.234','%','xuys','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
            update db set host = '%' where user = 'xuys';
            重復執行上面的第2、3步。

            posted @ 2008-04-17 14:01 隨意門 閱讀(180) | 評論 (0)編輯 收藏
            cvs服務器與wincvs的配置

            大概是兩年前,我從我一個考研的朋友那里聽到關于cvs和版本控制這兩個詞,當時他還教了我怎樣在windows平臺下配置wincvs和cvsnt。可 惜我當時并不在意這個,弄得現在配置這個東西花了我兩天的時間,值得安慰的是在參考了眾多網友的經驗之后總算配置成功。為此把我的經驗和教訓貼出來以表示 對網友們的謝意(很抱歉的是當時只顧著看怎么配置沒有記下各位網友的名字,ps自己一下)和對自己的鼓勵。以后會把如何在開發過程中的使用貼出來。本文主 要參考資料是:吳炎溪  Email:Yanxi-Wu@21cn.com的《cvs服務器與wincvs的配置與使用》,發在chinaunix上。

                我配置時服務器是redhat linux 9,客戶端是windows xp和wincvs。這里假定讀者已經安裝好了redhat linux 9和wincvs,如果不知道怎么安裝可以到網上搜一下。redhat linux 9的安裝我使用的完全安裝,就是把光盤里帶的所有東西都安裝上了。這樣的話所有的服務器和服務應該都有了,為了偷懶我還把linux上的防火墻給關掉了, 我是內部局域網使用,如果不是的話千萬不要把防火墻關了。(再ps自己一下)

            一、linux下的cvs服務器配置

            1、查看/etc/services文件:

                首先要看看/etc/services這個文件,以確認cvs服務和端口已經打開

            cvspserver 2401/tcp # cvs client/server operations 

            cvspserver 2401/udp # cvs client/server operations

            2、配置xinetd,用xinetd來啟動cvs服務器:

                進入到/etc/xinetd.d/目錄,在此目錄下編輯一個名字為cvspserver的文本文件,使用cvspserver作為文件名是因為在/etc/services中的入口名字是cvspserver。編輯如下:

            service cvspserver

            {

            disable = no

            protocol = tcp

            socket_type = stream

            port = 2401

            wait = no

            user = root

            env = HOME=

            server = /usr/bin/cvs

            server_args = -f --allow-root=/home/cvsroot pserver

            }

            注意:a、service后面的名稱一定要和你在/etc/service文件中的cvs服務名稱一樣;benv = HOME=這一行的目的就是為了解決在執行一些cvs操作時產生的讀取/root/.cvsignore文件的錯誤,上面env那行的意思就是在運行cvs服務的時候將環境變量HOME置空,這樣雖然執行cvs的用戶是root,但是由于沒有了HOME這個環境變量,所以cvs就不會在去讀取/root/.cvsignore文件了。

            3、配置cvs用戶組和cvsroot用戶

                首先建立一個用戶組cvs,記下cvs組ID。然后添加一個用戶cvsroot,然后修改/etc/passwd文件,把cvsroot用戶的組ID改為 剛才新建的cvs組的組ID。這樣在/home目錄下就會有一個/cvsroot目錄。修改/home/cvsroot的權限:#chomd 771 /home/cvsroot

            4、對cvs進行初始化:

                要使用cvs服務器首先要初始化cvs服務器的根目錄,這樣以后創建的cvs項目都將建立在這個目錄下:# cvs -d /home/cvsroot init

            5、登錄cvs服務器(在linux下登錄):

            #cvs -d :pserver:cvsroot@host:/home/cvsroot login

            CVS password//輸入用戶cvsroot的口令;

            如果沒有出現其它的任何提示就表示登錄成功了,否則要根據提示進行相應的修改。 下面對登錄命令的語法進行說明:

            其中,:pserver表示采用pserver方式進行用戶登錄認證,一般的CVS服務器都采用這

            種方式,當然也可以采用其它方式,具體參考相應的資料;

                 :cvsroot表示要登錄的用戶名,只要是cvs組的成員都可以,如:cather;

                 @host表示要登錄的服務器,可以是DNS名,也可以是IP地址,如:10.104.1.204;

            :/home/cvsroot表示CVS在服務器上的目錄,也可以是其它目錄(由第6中你所

            指定的用來做init初始化的目錄決定);

            提示:也可以把export CVSROOT=":pserver:jchuang"@192.168.0.8:/home/cvsroot這一句直

            接寫在用戶的初始化文件中(如:.bash_profile),這樣用戶每次登錄時,只需輸入:

            cvs login

                然后輸入相應的口令就可以登錄到cvs服務器上。

            b、如果是本地登錄,可以直接把export CVSROOT="/home/cvsroot"這一句寫在用戶的初

            始化文件如:.bash_profile中;然后直接輸入#cvs login,再輸入相應的口令就可以登錄到cvs服務器上了。

            二、WinCVS的配置

            1WinCVS簡介:

                WinCVSCVS的一個客戶端軟件,它運行在Windows上,用來在Windows上登錄CVS服務器,然后進行一些CVS相關的操作與管理。由于當前很多的企業內部都采用Linux/Unix做服務器,而用Windows做客戶端,所以,WinCVSCVS服務器配合使用將組成最強有力的版本控制與管理的系統之一。

            2、WinCVS的下載與安裝;

               最新的WinCVS可以從http://sourceforge.net/project/showfiles.php?group_id=10072地址下載到,也可以在http://sourceforge.net/project 上下載到最新的或其它版本的WinCVS。下載到相應的版本后根據向導進行安裝,已經要使用CVS的用戶,安裝這個WinCVS應該沒什么問題吧!

            3、配置WinCVS

            a、一般選項的設置,選擇Admin->references…,出現如下界面:

               

            第一、Authentication:用來配置cvs服務器的認證方式,可以從下拉框中選擇其它的認證方式,不過一般只要選擇默認的pserver方式就可以,要注意的是必須與cvs服務器配置時所指定的認證方式一致;

            第二、Path:用來配置cvs在服務器上的主目錄路徑,也就是服務器上用進行cvs初始化的目錄,如:/home/cvsroot

            第三、Host Address:用來配置cvs服務器所在服務器的地址,可以是IP地址,也可以是DNS名,如:10.104.1.204;

            第四、User name:用來配置要使用些WinCVS來登錄CVS服務器的用戶名,如:cvsyxwu,用戶的登錄必須由管理員把其添加cvs用戶組中;

            第五、CVSROOT:此項一般都不需要用戶進行修改,用戶在輸入上邊的幾個選項時,系統將自動根據用戶的輸入生成此項的相應內容。

            b、全局選項的設置,在上一個界面上選擇“Globals”:

               

               此項的配置主要是要注意這幾選項:

            第一,Checkout read-only不要選上,否則,checkout出來的源代碼將不允許用戶進行

            修改,并且此選項默認是選中的;

            第二,Prune (remove) empty directories也不要選上,否則,會自動刪除空目錄;

            第三,對一般配置沒有特殊要求的,把Dirty files support、Supply control when adding

            TCP/IP compression選項選中;

            4、登錄服務器:

            選擇Admin->;login,將出現如下對話框要求用戶輸入登錄口令

             

            輸入口令后,選擇“OK”按鈕,如果CVS服務器與WinCVS的配置都沒出錯的話,將在CVS的狀態欄中提示:

            cvs -z9 -d :pserver:cvsyxwu@10.104.1.204:/home/cvsroot login

            Logging in to :pserver:cvsyxwu@10.104.1.204:2401/home/cvsroot

            ***** CVS exited normally with code 0 *****

            code 0表示正確的登錄;而如果出錯的話,將是code 1,那么要根據錯誤的提示進行相應的修改。

            posted @ 2008-04-16 15:21 隨意門 閱讀(556) | 評論 (0)編輯 收藏
            系統自帶的最不起眼但又最強的殺毒工具

             Windows系統集成了無數的工具,它們各司其職,滿足用戶不同的應用需求。其實這些工具“多才多藝”,如果你有足夠的想象力并且善于挖掘,你會發現它們除了本行之外還可以幫我們殺毒。不信?你看吧!

              一、任務管理器給病毒背后一刀

              

              Windows任務管理器是大家對進程進行管理的主要工具,在它的“進程”選項卡中能查看當前系統進程信息。在默認設置下,一般只能看到映像名稱、用戶名、CPU占用、內存使用等幾項,而更多如I/O讀寫、虛擬內存大小等信息卻被隱藏了起來。可別小看了這些被隱藏的信息,當系統出現莫名其妙的故障時,沒準就能從它們中間找出突破口。

              1.查殺會自動消失的雙進程木馬

              前段時間朋友的電腦中了某木馬,通過任務管理器查出該木馬進程為“system.exe”,終止它后再刷新,它又會復活。進入安全模式把c:\windows\system32\system.exe刪除,重啟后它又會重新加載,怎么也無法徹底清除它。從此現象來看,朋友中的應該是雙進程木馬。這種木馬有監護進程,會定時進行掃描,一旦發現被監護的進程遭到查殺就會復活它。而且現在很多雙進程木馬互為監視,互相復活。因此查殺的關鍵是找到這“互相依靠”的兩個木馬文件。借助任務管理器的PID標識可以找到木馬進程。

              調出Windows任務管理器,首先在“查看→選擇列”中勾選“PID(進程標識符)”,這樣返回任務管理器窗口后可以看到每一個進程的PID標識。這樣當我們終止一個進程,它再生后通過PID標識就可以找到再生它的父進程。啟動命令提示符窗口,執行“taskkill /im system.exe /f”命令。刷新一下電腦后重新輸入上述命令如圖1,可以看到這次終止的system.exe進程的PID為1536,它屬于PID為676的某個進程。也就是說PID為1536的system.exe進程是由PID為676的進程創建的。返回任務管理器,通過查詢進程PID得知它就是“internet.exe”進程進程。(如圖)


              找到了元兇就好辦了,現在重新啟動系統進入安全模式,使用搜索功能找到木馬文件c:\windows\internet.exe ,然后將它們刪除即可。前面無法刪除system.exe,主要是由于沒有找到internet.exe(且沒有刪除其啟動鍵值),導致重新進入系統后internet.exe復活木馬。

              2.揪出狂寫硬盤的P2P程序

              單位一電腦一開機上網就發現硬盤燈一直閃個不停,硬盤狂旋轉。顯然是本機有什么程序正在進行數據的讀取,但是反復殺毒也沒發現病毒、木馬等惡意程序。

              打開該電腦并上網,按Ctrl+Alt+Del鍵啟動了任務管理器,切換到“進程”選項卡,點擊菜單命令“查看→選擇列”,同時勾選上“I/O寫入”和“I/O寫入字節”兩項。確定后返回任務管理器,發現一個陌生的進程hidel.exe,雖然它占用的CPU和內存并不是特別大,但是I/O的寫入量卻大得驚人,看來就是它在搗鬼了,趕緊右擊它并選擇“結束進程”終止,果然硬盤讀寫恢復正常了。

              二、系統備份工具殺毒于無形

              筆者曾遭遇一個無法刪除的病毒“C:\Program Files\Common Files\PCSuite\rasdf.exe”,同時也無法復制這個文件,如何清除它。筆者通過系統備份工具清除了該病毒,操作過程如下:

              第一步:單擊“開始→所有程序→附件→系統工具→備份”,打開備份或還原向導窗口,備份項目選擇“讓我選擇要備份的內容”,定位到“C:\Program Files\Common Files\PCSuite”。

              第二步:繼續執行備份向導操作,將備份文件保存為“g:\virus.bkf”,備份選項勾選“使用卷陰影復制”,剩余操作按默認設置完成備份。

              第三步:雙擊“g:\virus.bak”,打開備份或還原向導,把備份還原到“g:\virus”。接著打開“g:\virus”,使用記事本打開病毒文件“rasdf.exe”,然后隨便刪除其中幾行代碼并保存,這樣病毒就被我們使用記事本破壞了(它再也無法運行)。

              第四步:操作同上,重新制作“k:\virus”的備份為“k:\virus1.bkf”。然后啟動還原向導,還原位置選擇“C:\Program Files\Common Files\PCSuite\”,還原選項選擇“替換現有文件”。這樣,雖然當前病毒正在運行,但備份組件仍然可以使用壞的病毒文件替換當前病毒。還原完成后,系統提示重新啟動,重啟后病毒就不會啟動了(因為它已被記事本破壞)。

              三、記事本借刀殺人

              1.雙進程木馬的查殺

              現在,越來越多的木馬采用雙進程守護技術保護自己,就是兩個擁有同樣功能的代碼程序,不斷地檢測對方是否已經被別人終止,如果發現對方已經被終止了,那么又開始創建對方,這給我們的查殺帶來很大的困難。不過,此類木馬也有“軟肋”,它只通過進程列表進程名稱來判斷被守護進程是否存在。這樣,我們只要用記事本程序來替代木馬進程,就可以達到“欺騙”守護進程的目的。

              下面以某變種木馬的查殺為例。中招該木馬后,木馬的“internet.exe”和“systemtray.exe”兩個進程會互相監視。當然,我們中招的時候大多不知道木馬具體的監護進程。不過,通過進程名稱可以知道,“systemtray.exe”是異常的進程,因為系統正常進程中沒有該進程。下面使用替換方法來查殺該木馬。

              第一步:單擊“開始→運行”,輸入“Msinfo32”打開系統信息窗口,展開“系統摘要→軟件環境→正在運行任務”,這里可以看到“systemtray.exe”路徑在“C:\Windows\System32”下。

              第二步:打開“C:\Windows\System32”,復制記事本程序“notepad.exe”到“D:\” ,同時重命名為“systemtray.exe”。

              第三步:打開記事本程序,輸入下列代碼,保存為“shadu.bat”,放置在桌面(括號為注釋,無須輸入):

              @echo off

              Taskkill /f /im systemtray.exe (使用taskkill命令強行終止“systemtray.exe”進程)

              Delete C:\Windows\System32\systemtray.exe (刪除病毒文件)

              Copy d:\systemtray.exe C:\Windows\System32\(替換病毒文件)

              第四步:現在只要在桌面運行“shadu.bat”,系統會將“systemtray.exe”進程終止并刪除,同時把改名的記事本程序復制到系統目錄。這樣,守護進程會“誤以為”被守護進程還存在,它會立刻啟動一個記事本程序。

              第五步:接下來我們只要找出監視進程并刪除即可,在命令提示符輸入:

              “taskkill /f /im systemtray.exe ”,將守護進程再生的“systemtray.exe”終止,可以看到“systemtray.exe”進程是由“PID 3288的進程”創建的,打開任務管理器可以看到“PID 3288的進程”為“internet.exe”,這就是再生進程的“元兇”。

              第六步:按照第一步方式,打開系統信息窗口可以看到“internet.exe”也位于系統目錄,終止“internet.exe”進程并進入系統目錄把上述兩個文件刪除即可。

              2.使病毒失效并刪除

              大家知道,文件都是由編碼組成的,記事本程序理論上可以打開任意文件(只不過有些會顯示為亂碼)。我們可以將病毒打開方式關聯到記事本,使之啟動后變成由記事本打開,失去作惡的功能。比如,一些頑固病毒常常會在注冊表的“HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run”等啟動位置生成難以刪除的鍵值,達到惡意啟動的目的。下面使用記事本來“廢”掉病毒的生命力。

              第一步:啟動命令提示符,輸入“ftype exefile=notepad.exe %1”,把所有EXE程序打開方式關聯到記事本程序,重啟系統后我們會發現桌面自動啟動好幾個程序,這里包括系統正常的程序如輸入法、音量調整程序等,當然也包括惡意啟動的流氓程序,不過現在都被記事本打開了。

              第二步:根據記事本窗口標題找到病毒程序,比如上例的systemtray.exe程序,找到這個記事本窗口后,單擊“文件→另存為”,我們就可以看到病毒具體路徑在“C:\Windows\System32”下?,F在關掉記事本窗口,按上述路徑提示進入系統目錄刪除病毒即可。

              第三步:刪除病毒后就可以刪除病毒啟動鍵值了,接著重啟電腦,按住F8,然后在安全模式菜單選擇“帶命令提示的安全模式”,進入系統后會自動打開命令提示符。輸入“ftype exefile="%1"%*”恢復exe文件打開方式即可。

              四、注冊表映像劫持讓病毒沒脾氣

              現在病毒都會采用IFO的技術,通俗的講法是映像劫持,利用的是注冊表中的如下鍵值

              HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options位置來改變程序調用的,而病毒卻利用此處將正常的殺毒軟件給偷換成病毒程序。恰恰相反,讓我們自己可以利用此處欺瞞病毒木馬,讓它實效。可謂,瞞天過海,還治其人。

              下面我們以屏蔽某未知病毒KAVSVC.EXE為例,操作方法如下:

              第一步:先建立以下一文本文件,輸入以下內容,另存為1.reg

              Windows Registry Editor Version 5.00

              [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\KAVSVC.EXE]

              "Debugger"="d:\\1.exe"

              [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\KAVSVC.EXE]

              "Debugger"="d:\\1.exe"

              (注:第一行代碼下有空行。)

              第二步:雙擊導入該reg文件后,確定。

              第三步:點“開始→運行”后,輸入KAVSVC.EXE。

              提示:1.exe可以是任意無用的文件,是我們隨意創建一個文本文件后將后綴名.txt改為.exe的,

              總結:當我們飽受病毒木馬的折磨,在殺毒軟件無能為力或者感覺“殺雞焉用宰牛刀”時,不妨運用系統工具進行病毒木馬的查殺,說不定會起到意想不到的效果

            posted @ 2008-04-10 09:39 隨意門 閱讀(223) | 評論 (0)編輯 收藏
            僅列出標題
            共9頁: 1 2 3 4 5 6 7 8 9 
            久久亚洲中文字幕精品一区| 99久久国产亚洲综合精品| 欧美噜噜久久久XXX| 久久精品视频免费| 久久久久久久综合综合狠狠| 国产精品久久久久免费a∨| 韩国三级大全久久网站| 欧美性大战久久久久久| 久久亚洲精品中文字幕| 欧美日韩精品久久久免费观看 | 久久久无码一区二区三区| 人人狠狠综合久久亚洲婷婷| 99久久综合国产精品免费| 99久久99久久精品国产片果冻 | 狠狠久久亚洲欧美专区| 青青草国产97免久久费观看| 蜜臀av性久久久久蜜臀aⅴ麻豆| 久久er国产精品免费观看8| 久久久久99精品成人片欧美| 久久影院午夜理论片无码 | 狠狠色丁香婷婷综合久久来来去| 18岁日韩内射颜射午夜久久成人| 99精品伊人久久久大香线蕉 | 精品永久久福利一区二区| 欧美日韩精品久久久久| 88久久精品无码一区二区毛片| 色8久久人人97超碰香蕉987| 久久e热在这里只有国产中文精品99| 狠狠色丁香久久婷婷综| 久久久久久亚洲AV无码专区| 精品久久久久成人码免费动漫| 国产精品欧美久久久久天天影视 | 国产精品午夜久久| 国产麻豆精品久久一二三| 久久丫精品国产亚洲av不卡 | 精品国产乱码久久久久久1区2区| 色偷偷久久一区二区三区| 久久人做人爽一区二区三区 | 久久久国产精华液| 久久精品国产亚洲AV不卡| 久久综合久久伊人|