C Socket
小样例
发个C Socket的小样例了。来映衬下《Java Socket基础》^^。很久前的东西了,都忘的差不多了==。
一、概述
用来解析V6我秀的真实地址的,之后直接打开浏览纯净的视频?貌似是这样的。
附件工程是VS2010的win32程序,可以通过运行参数传房间号。执行解压工程Debug目录下的exe,或者里面个bat,改下房间号后运行。
二、AnalyzeUrl.cpp
- #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;
- } else {
- //printf("==%c==\n", *s);
- *(p++) = *s;
- }
- }
- }
- q =(char *)malloc(strlen(buf));
- return strcpy(q, buf);
- }
- // 从s1中截取以s2开始的后的''内容
- char * getContent(char *s1, char *s2) {
- int flag = 0;
- 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;
- }
- }
- s++;
- }
- }
- // 出现包含字符后
- if (flag == 1) {
- //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");
- break;
- }
- }
- }
- if (0 == hasFplayer) {
- fPlayer = getContent(text, "Fplayer:");
- // 如果读到了Fplayer
- if (fPlayer != NULL) {
- if(strlen(fPlayer) > 0) {
- hasFplayer = 1;
- printf("读到了Fplayer:%s\n\n", fPlayer);
- break;
- } else {
- //printf("未读到了Fplayer\n\n");
- break;
- }
- }
- }
- 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);
- }
- return NULL;
- }
- 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");
- } else {
- printf("解析地址:%s\n\n",newUrl);
- *buf = '\0';
- strcat(buf, "rundll32 url.dll,FileProtocolHandler \"");
- strcat(buf, newUrl);
- strcat(buf, "\"");
- system(buf);
- }
- printf("结束!\n\n");
- system("PAUSE");
- return 0;
- }
额,不熟,现在就更不熟了==。
三、Java版
这可有个Java版哦,用swing简单做了界面的。复制些功能性的主要代码了。
3.1
)VideoUtil.java
- 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;
- }
- // 如果读到了flvTitle
- if (!hasReadFlvTitle && s.indexOf("flvTitle:") != -1) {
- hasReadFlvTitle = true;
- flvTitle = getContent(s);
- // 没有内容时返回null
- if (null == flvTitle) {
- frame.addInfo("直播文件名信息为空,还未开始直播!");
- is.close();
- return null;
- } else {
- frame.addInfo("获取了直播文件名信息:" + flvTitle);
- }
- }
- // 如果读到了flvTitle
- if (!hasReadFplayer && s.indexOf("Fplayer:") != -1) {
- hasReadFplayer = true;
- fPlayer = getContent(s);
- // 没有内容时返回null
- if (null == fPlayer) {
- frame.addInfo("flash播放信息为空!");
- is.close();
- return null;
- } else {
- 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 null;
- }
- return str.substring(beginIndex + 1, endIndex);
- }
- // 获取网页输入流
- public static InputStream getNetInputStream(String urlStr, InfoFrame frame) {
- try {
- 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;
- }
- }
3.2
)打开浏览器(网上弄的)
- // 打开浏览器访问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);
- } else {
- // 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();
- }
- }
四、后记
额,VS工程没清理好像,还挺大==。总之,玩玩呗~。那时是想弄优酷的,印象中好像加密拆分了什么的,不过后来……我承认我是6房间看MM去了……
ps:附件放个打包成的jar,运行试试呗。工程下载至Click here!