<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), &WSAData))
{
printf("WSA failed!\n");
return NULL;
* 分離url中的主機位址和相對路徑
strcpy(myurl, url);
for (pHost = myurl; *pHost != '/' && *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->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 *)&addr,sizeof(addr));
send(sockfd, header, strlen(header), 0);
printf("開始分析網頁代碼...\n\n");
while (1)
if (recv(sockfd, text, BUFSIZ, 0) > 0) {
//printf("\n\n==========\n\n");
//printf("%s", text);
if (0 == hasFlvTitle) {
flvTitle = getContent(text, "flvTitle:");
// 如果讀到了flvTitle
if (flvTitle != NULL) {
if (strlen(flvTitle) > 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) > 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 && 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, "&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 > 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 && s.indexOf("flvTitle:") != -1) {
hasReadFlvTitle = true;
flvTitle = getContent(s);
// 沒有内容時傳回null
if (null == flvTitle) {
frame.addInfo("直播檔案名資訊為空,還未開始直播!");
is.close();
return null;
frame.addInfo("擷取了直播檔案名資訊:" + flvTitle);
if (!hasReadFplayer && 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
+ "&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 < browsers.length && 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,如需轉載請自行聯系原作者