C Socket 小样例

         发个C Socket的小样例了。来映衬下《Java Socket基础》^^。很久前的东西了,都忘的差不多了==。

 
一、概述
         用来解析V6我秀的真实地址的,之后直接打开浏览纯净的视频?貌似是这样的。
         附件工程是VS2010的win32程序,可以通过运行参数传房间号。执行解压工程Debug目录下的exe,或者里面个bat,改下房间号后运行。
 
二、AnalyzeUrl.cpp
 
  
  1. #include "stdafx.h" 
  2.  
  3. // 字符缓冲 
  4. static char buf[BUFSIZ]; 
  5.  
  6. // 截取字符串首个''内内容 
  7. char * truncate(char *s) { 
  8.     int flag = 0; 
  9.     char *p, *q; 
  10.     p = buf; 
  11.     // 不是字符串末尾 
  12.     while (*s != '\0') { 
  13.         // 如果未遇到了字符' 
  14.         if (flag == 0) { 
  15.             // 如果字符为'时 
  16.             if (*s == '\'') { 
  17.                 //printf("首次遇到符号==%c==\n", *s); 
  18.                 flag = 1; 
  19.             } else { 
  20.                 s++; 
  21.             } 
  22.         } 
  23.         // 如果遇到了首个字符 
  24.         if (flag == 1) { 
  25.             // 如果下个符号为'或到底时 
  26.             s++; 
  27.             if (*s == '\'' || *s == '\0' ) { 
  28.                 //printf("再次遇到符号==%c==\n", *s); 
  29.                 // 字符串结尾标记 
  30.                 *p = '\0'
  31.                 break
  32.             } else { 
  33.                 //printf("==%c==\n", *s); 
  34.                 *(p++) = *s; 
  35.             } 
  36.         } 
  37.     } 
  38.     q =(char *)malloc(strlen(buf)); 
  39.     return strcpy(q, buf); 
  40.  
  41. // 从s1中截取以s2开始的后的''内容 
  42. char * getContent(char *s1, char *s2) { 
  43.     int flag = 0; 
  44.     char *p, *q, *s; 
  45.     p = s1; 
  46.     while (*p != '\0') { 
  47.         // 等于s2首字符时 
  48.         if (*p == *s2) { 
  49.             flag = 1; 
  50.             s = p; 
  51.             q = s2; 
  52.             // 判断接下去的字符是否相等 
  53.             while (*q != '\0') { 
  54.                 // s1读至了末尾 
  55.                 if (*s == '\0') { 
  56.                     flag = 0; 
  57.                     break
  58.                 } else { 
  59.                     if (*q++ != *s) { 
  60.                         flag = 0; 
  61.                         break
  62.                     } 
  63.                 } 
  64.                 s++; 
  65.             } 
  66.         } 
  67.         // 出现包含字符后 
  68.         if (flag == 1) { 
  69.             //printf("==%c==\n", *(p + 1)); 
  70.             return truncate(s); 
  71.         } 
  72.         p++; 
  73.     } 
  74.     return NULL; 
  75.  
  76. char * analyzeUrl(char *url) 
  77.     WSADATA WSAData={0}; 
  78.     SOCKET sockfd; 
  79.     struct sockaddr_in addr; 
  80.     struct hostent *pURL; 
  81.     char myurl[BUFSIZ]; 
  82.     char *pHost = 0, *pGET = 0; 
  83.     char host[BUFSIZ], GET[BUFSIZ]; 
  84.     char header[BUFSIZ] = ""
  85.     // 扩大点,一次性读进去 
  86.     static char text[BUFSIZ]; 
  87.  
  88.     // 解析后信息 
  89.     int hasFlvTitle = 0, hasFplayer = 0; 
  90.     char *flvTitle, *fPlayer, *result; 
  91.  
  92.     /* 
  93.     * windows下使用socket必须用WSAStartup初始化,否则不能调用 
  94.     */ 
  95.     if(WSAStartup(MAKEWORD(2,2), &WSAData)) 
  96.     { 
  97.         printf("WSA failed!\n"); 
  98.         return NULL; 
  99.     } 
  100.  
  101.     /* 
  102.     * 分离url中的主机地址和相对路径 
  103.     */ 
  104.     strcpy(myurl, url); 
  105.     for (pHost = myurl; *pHost != '/' && *pHost != '\0'; ++pHost); 
  106.     if ( (int)(pHost - myurl) == strlen(myurl) ) 
  107.         strcpy(GET, "/"); 
  108.     else 
  109.         strcpy(GET, pHost); 
  110.     *pHost = '\0'
  111.     strcpy(host, myurl); 
  112.     printf("网页地址:http://%s%s\n\n", host, GET); 
  113.  
  114.     /* 
  115.     * 设定socket参数,并未真正初始化 
  116.     */ 
  117.     sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); 
  118.     pURL = gethostbyname(host); 
  119.     addr.sin_family = AF_INET; 
  120.     addr.sin_addr.s_addr = *((unsigned long*)pURL->h_addr); 
  121.     addr.sin_port = htons(80); 
  122.  
  123.     /* 
  124.     * 组织发送到web服务器的信息 
  125.     * 为何要发送下面的信息请参考HTTP协议的约定 
  126.     */ 
  127.     strcat(header, "GET "); 
  128.     strcat(header, GET); 
  129.     strcat(header, " HTTP/1.1\r\n"); 
  130.     strcat(header, "HOST: "); 
  131.     strcat(header, host); 
  132.     strcat(header, "\r\nConnection: Close\r\n\r\n"); 
  133.  
  134.     /* 
  135.     * 连接到服务器,发送请求header,并接受反馈(即网页源代码) 
  136.     */ 
  137.     printf("正在获取网页代码...\n\n"); 
  138.     connect(sockfd,(SOCKADDR *)&addr,sizeof(addr)); 
  139.  
  140.     send(sockfd, header, strlen(header), 0); 
  141.      
  142.     printf("开始分析网页代码...\n\n"); 
  143.     while (1) 
  144.     { 
  145.         if (recv(sockfd, text, BUFSIZ, 0) > 0) { 
  146.             //printf("\n\n==========\n\n"); 
  147.             //printf("%s", text); 
  148.  
  149.             if (0 == hasFlvTitle) { 
  150.                 flvTitle = getContent(text, "flvTitle:"); 
  151.                 // 如果读到了flvTitle 
  152.                 if (flvTitle != NULL) { 
  153.                     if (strlen(flvTitle) > 0) { 
  154.                         hasFlvTitle = 1; 
  155.                         printf("读到了flvTitle:%s\n\n", flvTitle); 
  156.                     } else { 
  157.                         //printf("未读到了flvTitle\n\n"); 
  158.                         break
  159.                     } 
  160.                 } 
  161.             } 
  162.  
  163.             if (0 == hasFplayer) { 
  164.                 fPlayer = getContent(text, "Fplayer:"); 
  165.                 // 如果读到了Fplayer 
  166.                 if (fPlayer != NULL) { 
  167.                     if(strlen(fPlayer) > 0) { 
  168.                         hasFplayer = 1; 
  169.                         printf("读到了Fplayer:%s\n\n", fPlayer); 
  170.                         break
  171.                     } else { 
  172.                         //printf("未读到了Fplayer\n\n"); 
  173.                         break
  174.                     } 
  175.                 } 
  176.             } 
  177.  
  178.             strnset(text, '\0', BUFSIZ); 
  179.         } else { 
  180.             break
  181.         } 
  182.     } 
  183.      
  184.     closesocket(sockfd); 
  185.     WSACleanup(); 
  186.  
  187.     if (1 == hasFlvTitle && 1 == hasFplayer) { 
  188.         //printf("==flvTitle:%s==\n\n", flvTitle); 
  189.         //printf("==Fplayer:%s==\n\n", fPlayer); 
  190.         *buf = '\0'
  191.         strcat(buf, "http://v.6.cn"); 
  192.         strcat(buf, fPlayer); 
  193.         strcat(buf, "?fileName="); 
  194.         strcat(buf, flvTitle); 
  195.         strcat(buf, "&autoplay=true"); 
  196.  
  197.         result =(char *)malloc(strlen(buf)); 
  198.  
  199.         return strcpy(result, buf); 
  200.     } 
  201.  
  202.     return NULL; 
  203.  
  204.  
  205. int main(int argc, char * argv[]) 
  206. //int _tmain(int argc, _TCHAR* argv[]) 
  207.     *buf = '\0'
  208.     char *url, *newUrl; 
  209.     if (argc > 1) { 
  210.         strcat(buf, "v.6.cn/"); 
  211.         strcat(buf, *(argv+1)); 
  212.         url =(char *)malloc(strlen(buf)); 
  213.         strcpy(url, buf); 
  214.         //printf("==%s==\n\n", *(argv+1)); 
  215.     } else { 
  216.         url = "v.6.cn/541218"
  217.     } 
  218.  
  219.     printf("开始...\n\n"); 
  220.  
  221.     newUrl = analyzeUrl(url); 
  222.     if (newUrl == NULL) { 
  223.         printf("未解析到地址/(ㄒoㄒ)/~~\n\n"); 
  224.     } else { 
  225.         printf("解析地址:%s\n\n",newUrl); 
  226.         *buf = '\0'
  227.         strcat(buf, "rundll32 url.dll,FileProtocolHandler \""); 
  228.         strcat(buf, newUrl); 
  229.         strcat(buf, "\""); 
  230.         system(buf); 
  231.     } 
  232.  
  233.     printf("结束!\n\n"); 
  234.  
  235.     system("PAUSE"); 
  236.     return 0; 
 
         额,不熟,现在就更不熟了==。
 
三、Java版
         这可有个Java版哦,用swing简单做了界面的。复制些功能性的主要代码了。
 
3.1 )VideoUtil.java
 
  
  1. public class VideoUtil { 
  2.  
  3.     // 连接超时15秒 
  4.     public static final int TIMEOUT = 15
  5.  
  6.     // 读取源代码时判断获得js代码page对象中的flvTitle(直播文件名)和Fplayer(播放地址),并且由其组成真实地址 
  7.     public static String getVideoRealUrl(String urlStr, InfoFrame frame) { 
  8.         String flvTitle = "", fPlayer = ""
  9.         try { 
  10.             frame.addInfo("网页地址:" + urlStr); 
  11.             frame.addInfo("正在获取网页代码..."); 
  12.             InputStream is = getNetInputStream(urlStr, frame); // 获取网页输入流 
  13.             if (null == is) { 
  14.                 frame.addInfo("解析超时或者地址有误O__O\"…"); 
  15.                 return null
  16.             } 
  17.  
  18.             frame.addInfo("开始分析网页代码..."); 
  19.             InputStreamReader isr = new InputStreamReader(is); 
  20.             BufferedReader br = new BufferedReader(isr); 
  21.             String s = null
  22.             boolean hasReadFlvTitle = false, hasReadFplayer = false
  23.             while (true) { 
  24.                 s = br.readLine(); 
  25.                 if (null == s) { 
  26.                     is.close(); 
  27.                     frame.addInfo("该直播房间异常,请重新选择!"); 
  28.                     return null
  29.                 } 
  30.  
  31.                 // 如果读到了flvTitle 
  32.                 if (!hasReadFlvTitle && s.indexOf("flvTitle:") != -1) { 
  33.                     hasReadFlvTitle = true
  34.                     flvTitle = getContent(s); 
  35.                     // 没有内容时返回null 
  36.                     if (null == flvTitle) { 
  37.                         frame.addInfo("直播文件名信息为空,还未开始直播!"); 
  38.                         is.close(); 
  39.                         return null
  40.                     } else { 
  41.                         frame.addInfo("获取了直播文件名信息:" + flvTitle); 
  42.                     } 
  43.                 } 
  44.  
  45.                 // 如果读到了flvTitle 
  46.                 if (!hasReadFplayer && s.indexOf("Fplayer:") != -1) { 
  47.                     hasReadFplayer = true
  48.                     fPlayer = getContent(s); 
  49.                     // 没有内容时返回null 
  50.                     if (null == fPlayer) { 
  51.                         frame.addInfo("flash播放信息为空!"); 
  52.                         is.close(); 
  53.                         return null
  54.                     } else { 
  55.                         frame.addInfo("获取了flash播放信息:" + fPlayer); 
  56.                         break// 跳出循环 
  57.                     } 
  58.                 } 
  59.  
  60.             } 
  61.             is.close(); 
  62.         } catch (IOException e) { 
  63.             frame.addInfo("发生异常!"); 
  64.             e.printStackTrace(); 
  65.             return null
  66.         } 
  67.         return "http://v.6.cn" + fPlayer + "?fileName=" + flvTitle 
  68.                 + "&autoplay=true"
  69.     } 
  70.  
  71.     // 获取一个字符串''中的内容 
  72.     private static String getContent(String str) { 
  73.         int beginIndex = str.indexOf("'"); 
  74.         int endIndex = str.lastIndexOf("'"); 
  75.         if (beginIndex + 1 == endIndex) { 
  76.             return null
  77.         } 
  78.         return str.substring(beginIndex + 1, endIndex); 
  79.     } 
  80.  
  81.     // 获取网页输入流 
  82.     public static InputStream getNetInputStream(String urlStr, InfoFrame frame) { 
  83.         try { 
  84.             URL url = new URL(urlStr); 
  85.             URLConnection conn = url.openConnection(); 
  86.             conn.setRequestProperty( 
  87.                     "User-Agent"
  88.                     "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)"); 
  89.             conn.setConnectTimeout(TIMEOUT * 1000); 
  90.             conn.connect(); 
  91.             InputStream is = conn.getInputStream(); 
  92.             return is; 
  93.         } catch (Exception e) { 
  94.         } 
  95.         return null
  96.     } 
  97.  
 
3.2 )打开浏览器(网上弄的)
 
  
  1. // 打开浏览器访问url 
  2. public static void openURL(String url) { 
  3.     String osName = System.getProperty("os.name"); 
  4.     try { 
  5.         if (osName.startsWith("Mac OS")) { 
  6.             // Mac 
  7.             Class fileMgr = Class.forName("com.apple.eio.FileManager"); 
  8.             Method openURL = fileMgr.getDeclaredMethod("openURL"
  9.                     new Class[] { String.class }); 
  10.             openURL.invoke(nullnew Object[] { url }); 
  11.         } else if (osName.startsWith("Windows")) { 
  12.             // Windows 
  13.             Runtime.getRuntime().exec( 
  14.                     "rundll32 url.dll,FileProtocolHandler " + url); 
  15.         } else { 
  16.             // assume Unix or Linux 
  17.             String[] browsers = { "firefox""opera""konqueror"
  18.                     "epiphany""mozilla""netscape" }; 
  19.             String browser = null
  20.             for (int count = 0; count < browsers.length && browser == null; count++) { 
  21.                 if (Runtime.getRuntime() 
  22.                         .exec(new String[] { "which", browsers[count] }) 
  23.                         .waitFor() == 0) { 
  24.                     browser = browsers[count]; 
  25.                 } 
  26.             } 
  27.             if (browser != null) { 
  28.                 Runtime.getRuntime().exec(new String[] { browser, url }); 
  29.             } 
  30.         } 
  31.     } catch (Exception e) { 
  32.         e.printStackTrace(); 
  33.     } 
 
四、后记
         额,VS工程没清理好像,还挺大==。总之,玩玩呗~。那时是想弄优酷的,印象中好像加密拆分了什么的,不过后来……我承认我是6房间看MM去了……
 

         ps:附件放个打包成的jar,运行试试呗。工程下载至Click here