天天看點

C Socket小樣例

<b>C Socket</b><b>小樣例</b>

         發個C Socket的小樣例了。來映襯下《Java Socket基礎》^^。很久前的東西了,都忘的差不多了==。

<b>一、概述</b>

         用來解析V6我秀的真實位址的,之後直接打開浏覽純淨的視訊?貌似是這樣的。

         附件工程是VS2010的win32程式,可以通過運作參數傳房間号。執行解壓工程Debug目錄下的exe,或者裡面個bat,改下房間号後運作。

<b>二、AnalyzeUrl.cpp</b>

#include "stdafx.h" 

// 字元緩沖 

static char buf[BUFSIZ]; 

// 截取字元串首個''内内容 

char * truncate(char *s) { 

    int flag = 0; 

    char *p, *q; 

    p = buf; 

    // 不是字元串末尾 

    while (*s != '\0') { 

        // 如果未遇到了字元' 

        if (flag == 0) { 

            // 如果字元為'時 

            if (*s == '\'') { 

                //printf("首次遇到符号==%c==\n", *s); 

                flag = 1; 

            } else { 

                s++; 

            } 

        } 

        // 如果遇到了首個字元 

        if (flag == 1) { 

            // 如果下個符号為'或到底時 

            s++; 

            if (*s == '\'' || *s == '\0' ) { 

                //printf("再次遇到符号==%c==\n", *s); 

                // 字元串結尾标記 

                *p = '\0'; 

                break; 

                //printf("==%c==\n", *s); 

                *(p++) = *s; 

    } 

    q =(char *)malloc(strlen(buf)); 

    return strcpy(q, buf); 

// 從s1中截取以s2開始的後的''内容 

char * getContent(char *s1, char *s2) { 

    char *p, *q, *s; 

    p = s1; 

    while (*p != '\0') { 

        // 等于s2首字元時 

        if (*p == *s2) { 

            flag = 1; 

            s = p; 

            q = s2; 

            // 判斷接下去的字元是否相等 

            while (*q != '\0') { 

                // s1讀至了末尾 

                if (*s == '\0') { 

                    flag = 0; 

                    break; 

                } else { 

                    if (*q++ != *s) { 

                        flag = 0; 

                        break; 

                    } 

                } 

        // 出現包含字元後 

            //printf("==%c==\n", *(p + 1)); 

            return truncate(s); 

        p++; 

    return NULL; 

char * analyzeUrl(char *url) 

    WSADATA WSAData={0}; 

    SOCKET sockfd; 

    struct sockaddr_in addr; 

    struct hostent *pURL; 

    char myurl[BUFSIZ]; 

    char *pHost = 0, *pGET = 0; 

    char host[BUFSIZ], GET[BUFSIZ]; 

    char header[BUFSIZ] = ""; 

    // 擴大點,一次性讀進去 

    static char text[BUFSIZ]; 

    // 解析後資訊 

    int hasFlvTitle = 0, hasFplayer = 0; 

    char *flvTitle, *fPlayer, *result; 

    /* 

    * windows下使用socket必須用WSAStartup初始化,否則不能調用 

    */ 

    if(WSAStartup(MAKEWORD(2,2), &amp;WSAData)) 

    { 

        printf("WSA failed!\n"); 

        return NULL; 

    * 分離url中的主機位址和相對路徑 

    strcpy(myurl, url); 

    for (pHost = myurl; *pHost != '/' &amp;&amp; *pHost != '\0'; ++pHost); 

    if ( (int)(pHost - myurl) == strlen(myurl) ) 

        strcpy(GET, "/"); 

    else 

        strcpy(GET, pHost); 

    *pHost = '\0'; 

    strcpy(host, myurl); 

    printf("網頁位址:http://%s%s\n\n", host, GET); 

    * 設定socket參數,并未真正初始化 

    sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); 

    pURL = gethostbyname(host); 

    addr.sin_family = AF_INET; 

    addr.sin_addr.s_addr = *((unsigned long*)pURL-&gt;h_addr); 

    addr.sin_port = htons(80); 

    * 組織發送到web伺服器的資訊 

    * 為何要發送下面的資訊請參考HTTP協定的約定 

    strcat(header, "GET "); 

    strcat(header, GET); 

    strcat(header, " HTTP/1.1\r\n"); 

    strcat(header, "HOST: "); 

    strcat(header, host); 

    strcat(header, "\r\nConnection: Close\r\n\r\n"); 

    * 連接配接到伺服器,發送請求header,并接受回報(即網頁源代碼) 

    printf("正在擷取網頁代碼...\n\n"); 

    connect(sockfd,(SOCKADDR *)&amp;addr,sizeof(addr)); 

    send(sockfd, header, strlen(header), 0); 

    printf("開始分析網頁代碼...\n\n"); 

    while (1) 

        if (recv(sockfd, text, BUFSIZ, 0) &gt; 0) { 

            //printf("\n\n==========\n\n"); 

            //printf("%s", text); 

            if (0 == hasFlvTitle) { 

                flvTitle = getContent(text, "flvTitle:"); 

                // 如果讀到了flvTitle 

                if (flvTitle != NULL) { 

                    if (strlen(flvTitle) &gt; 0) { 

                        hasFlvTitle = 1; 

                        printf("讀到了flvTitle:%s\n\n", flvTitle); 

                    } else { 

                        //printf("未讀到了flvTitle\n\n"); 

            if (0 == hasFplayer) { 

                fPlayer = getContent(text, "Fplayer:"); 

                // 如果讀到了Fplayer 

                if (fPlayer != NULL) { 

                    if(strlen(fPlayer) &gt; 0) { 

                        hasFplayer = 1; 

                        printf("讀到了Fplayer:%s\n\n", fPlayer); 

                        //printf("未讀到了Fplayer\n\n"); 

            strnset(text, '\0', BUFSIZ); 

        } else { 

            break; 

    closesocket(sockfd); 

    WSACleanup(); 

    if (1 == hasFlvTitle &amp;&amp; 1 == hasFplayer) { 

        //printf("==flvTitle:%s==\n\n", flvTitle); 

        //printf("==Fplayer:%s==\n\n", fPlayer); 

        *buf = '\0'; 

        strcat(buf, "http://v.6.cn"); 

        strcat(buf, fPlayer); 

        strcat(buf, "?fileName="); 

        strcat(buf, flvTitle); 

        strcat(buf, "&amp;autoplay=true"); 

        result =(char *)malloc(strlen(buf)); 

        return strcpy(result, buf); 

int main(int argc, char * argv[]) 

//int _tmain(int argc, _TCHAR* argv[]) 

    *buf = '\0'; 

    char *url, *newUrl; 

    if (argc &gt; 1) { 

        strcat(buf, "v.6.cn/"); 

        strcat(buf, *(argv+1)); 

        url =(char *)malloc(strlen(buf)); 

        strcpy(url, buf); 

        //printf("==%s==\n\n", *(argv+1)); 

    } else { 

        url = "v.6.cn/541218"; 

    printf("開始...\n\n"); 

    newUrl = analyzeUrl(url); 

    if (newUrl == NULL) { 

        printf("未解析到位址/(ㄒoㄒ)/~~\n\n"); 

        printf("解析位址:%s\n\n",newUrl); 

        strcat(buf, "rundll32 url.dll,FileProtocolHandler \""); 

        strcat(buf, newUrl); 

        strcat(buf, "\""); 

        system(buf); 

    printf("結束!\n\n"); 

    system("PAUSE"); 

    return 0; 

         額,不熟,現在就更不熟了==。

<b>三、Java版</b>

         這可有個Java版哦,用swing簡單做了界面的。複制些功能性的主要代碼了。

<b>3.1</b><b>)VideoUtil.java</b>

public class VideoUtil { 

    // 連接配接逾時15秒 

    public static final int TIMEOUT = 15; 

    // 讀取源代碼時判斷獲得js代碼page對象中的flvTitle(直播檔案名)和Fplayer(播放位址),并且由其組成真實位址 

    public static String getVideoRealUrl(String urlStr, InfoFrame frame) { 

        String flvTitle = "", fPlayer = ""; 

        try { 

            frame.addInfo("網頁位址:" + urlStr); 

            frame.addInfo("正在擷取網頁代碼..."); 

            InputStream is = getNetInputStream(urlStr, frame); // 擷取網頁輸入流 

            if (null == is) { 

                frame.addInfo("解析逾時或者位址有誤O__O\"…"); 

                return null; 

            frame.addInfo("開始分析網頁代碼..."); 

            InputStreamReader isr = new InputStreamReader(is); 

            BufferedReader br = new BufferedReader(isr); 

            String s = null; 

            boolean hasReadFlvTitle = false, hasReadFplayer = false; 

            while (true) { 

                s = br.readLine(); 

                if (null == s) { 

                    is.close(); 

                    frame.addInfo("該直播房間異常,請重新選擇!"); 

                    return null; 

                if (!hasReadFlvTitle &amp;&amp; s.indexOf("flvTitle:") != -1) { 

                    hasReadFlvTitle = true; 

                    flvTitle = getContent(s); 

                    // 沒有内容時傳回null 

                    if (null == flvTitle) { 

                        frame.addInfo("直播檔案名資訊為空,還未開始直播!"); 

                        is.close(); 

                        return null; 

                        frame.addInfo("擷取了直播檔案名資訊:" + flvTitle); 

                if (!hasReadFplayer &amp;&amp; s.indexOf("Fplayer:") != -1) { 

                    hasReadFplayer = true; 

                    fPlayer = getContent(s); 

                    if (null == fPlayer) { 

                        frame.addInfo("flash播放資訊為空!"); 

                        frame.addInfo("擷取了flash播放資訊:" + fPlayer); 

                        break; // 跳出循環 

            is.close(); 

        } catch (IOException e) { 

            frame.addInfo("發生異常!"); 

            e.printStackTrace(); 

            return null; 

        return "http://v.6.cn" + fPlayer + "?fileName=" + flvTitle 

                + "&amp;autoplay=true"; 

    // 擷取一個字元串''中的内容 

    private static String getContent(String str) { 

        int beginIndex = str.indexOf("'"); 

        int endIndex = str.lastIndexOf("'"); 

        if (beginIndex + 1 == endIndex) { 

        return str.substring(beginIndex + 1, endIndex); 

    // 擷取網頁輸入流 

    public static InputStream getNetInputStream(String urlStr, InfoFrame frame) { 

            URL url = new URL(urlStr); 

            URLConnection conn = url.openConnection(); 

            conn.setRequestProperty( 

                    "User-Agent", 

                    "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.0.15) Gecko/2009101601 Firefox/3.0.15 (.NET CLR 3.5.30729)"); 

            conn.setConnectTimeout(TIMEOUT * 1000); 

            conn.connect(); 

            InputStream is = conn.getInputStream(); 

            return is; 

        } catch (Exception e) { 

        return null; 

<b>3.2</b><b>)打開浏覽器(網上弄的)</b>

// 打開浏覽器通路url 

public static void openURL(String url) { 

    String osName = System.getProperty("os.name"); 

    try { 

        if (osName.startsWith("Mac OS")) { 

            // Mac 

            Class fileMgr = Class.forName("com.apple.eio.FileManager"); 

            Method openURL = fileMgr.getDeclaredMethod("openURL", 

                    new Class[] { String.class }); 

            openURL.invoke(null, new Object[] { url }); 

        } else if (osName.startsWith("Windows")) { 

            // Windows 

            Runtime.getRuntime().exec( 

                    "rundll32 url.dll,FileProtocolHandler " + url); 

            // assume Unix or Linux 

            String[] browsers = { "firefox", "opera", "konqueror", 

                    "epiphany", "mozilla", "netscape" }; 

            String browser = null; 

            for (int count = 0; count &lt; browsers.length &amp;&amp; browser == null; count++) { 

                if (Runtime.getRuntime() 

                        .exec(new String[] { "which", browsers[count] }) 

                        .waitFor() == 0) { 

                    browser = browsers[count]; 

            if (browser != null) { 

                Runtime.getRuntime().exec(new String[] { browser, url }); 

    } catch (Exception e) { 

        e.printStackTrace(); 

<b>四、後記</b>

         額,VS工程沒清理好像,還挺大==。總之,玩玩呗~。那時是想弄優酷的,印象中好像加密拆分了什麼的,不過後來……我承認我是6房間看MM去了……

<a href="http://down.51cto.com/data/2360759" target="_blank">附件:http://down.51cto.com/data/2360759</a>

     本文轉自winorlose2000 51CTO部落格,原文連結:http://blog.51cto.com/vaero/893868,如需轉載請自行聯系原作者