Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >http协议户端下载流程

http协议户端下载流程

作者头像
用户4148957
发布于 2022-06-14 00:19:43
发布于 2022-06-14 00:19:43
3400
举报
文章被收录于专栏:C/C++与音视频C/C++与音视频

/************************************************************************************** 功能:http协议客户端网络下载测试 时间:2014-03-09 version : V1.0 说明:http协议客户端工作要点 1.创建socketbind本地socket,发起连接connetct ,完成tcp三次握手 2.向服务器发起http请求,即post或get动作,http协议请求格式见   http协议规范  3.读http响应,可以判定http 服务器和客户端是否通讯正常,如果失败,  可以根据错误代码判定不成功原因。  http 响应和http 错误代码见http协议部分  4.http响应会返回内容的长度和内容类型,这个信息在在在线业务中是个  非常有用的信息,比如流媒体是边看边下载,如果要计算流媒体长度  只能从http响应读取。 ***************************************************************************************/ #include <fcntl.h> #include <sys/syscall.h> #include <sys/mman.h> #include <stdio.h> #include <unistd.h> #include <string.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> #include <sys/types.h> #include <errno.h> #include <stdlib.h> #define SERVER_PORT 5000 #define BUF_MASK 0x1ff #define BUF_SIZE (188*7*64) #define O_DIRECT 0x8000 void usage() {     printf("Usage: http_test_client: -d <srv-ip> -p <srv-port> -f <content-file> [-h -a -v]\n");     printf("options are:\n");     printf(" -d <srv-ip>   # IP address of HTTP Server (e.g. 192.168.1.110)\n");     printf(" -p <srv-port> # Port of HTTP Server (e.g. 5000)\n");     printf(" -f <file>     # url of stream; /data/videos prepended (e.g. portugal.mpg) \n");     printf(" -m            # just leave content in memory, dont write to disk (default: write to file)\n");     printf(" -v            # print periodic stats (default: no)\n");     printf(" -h            # prints http_test_client usage\n");     printf("\n"); } double difftime1(struct timeval *start, struct timeval *stop) { double dt = 1000000.*(stop->tv_sec - start->tv_sec) + (stop->tv_usec - start->tv_usec); return dt; } /* This function creates a TCP connection to server and returns the socket descriptor */ int TcpConnect(char *server, int port, int socket_type) { int sd,rc; struct sockaddr_in localAddr, servAddr; struct hostent *h; printf("TCP - Connection to %s:%d ...\n",server, port); h = gethostbyname(server); if (h == NULL) { perror("Unknown Host"); return (-EINVAL); } servAddr.sin_family = h->h_addrtype; memcpy((char *) &servAddr.sin_addr.s_addr, h->h_addr_list[0],h->h_length); servAddr.sin_port = htons(port); /* Open Socket */ sd = socket(AF_INET, socket_type, 0); if (sd<0) { perror("Socket Open Err"); return -EINVAL; } localAddr.sin_family = AF_INET; localAddr.sin_addr.s_addr = htonl(INADDR_ANY); localAddr.sin_port = htons(0); if (bind(sd,(struct sockaddr *) &localAddr, sizeof(localAddr))) { perror("Socket Bind Err"); return -EINVAL; } /* Connect to server */ rc = connect(sd, (struct sockaddr *) &servAddr, sizeof(servAddr)); if (rc<0) { perror("Connect Error: Server busy or unavailable:"); return -EBUSY; } printf("TCP: Connection Success\n"); return sd; } #define PKTS_PER_READ 64 #define MAX_BUFFER_SIZE (1316 * PKTS_PER_READ) #define HTTP_POST_SIZE 2048 int main(int argc, char **argv) { char *post; char *server = NULL; char *fname = NULL; int maxrate = 19; int c; int sd; FILE *fp = NULL; char *p; char *rbuf; int  port = 0; ssize_t n; unsigned char *buf, *xbuf; ssize_t bytes = 0; unsigned long total=0; unsigned long count=0; char tok; ssize_t len; double dt; struct timeval start, stop; int accel_socket = 0;   /* Use Standard Socket */ int dont_write_to_disk = 0; int verbose = 0;         char cname ='/';     while ((c = getopt(argc, argv, "d:p:f:amvh")) != -1) {         switch (c) {         case 'd':             server = optarg;             break;         case 'p':             port = atoi(optarg);             break;         case 'f':             fname = optarg;             break;         case 'a':             accel_socket = 1;             break;         case 'm':             dont_write_to_disk = 1;             break;         case 'v':             verbose = 1;             break;         case 'h':         default:             usage();             return -1;         }     } if (port == 0 || server == NULL || fname == NULL) { printf("Missing Args...\n"); usage(); exit(1); } printf("Server %s, Port %d, File %s, Maxrate %d\n", server, port, fname, maxrate); xbuf = (unsigned char *) malloc(BUF_SIZE + BUF_MASK); rbuf = (char *) malloc(1024); post = (char *) malloc(HTTP_POST_SIZE); if (xbuf == NULL || rbuf == NULL || post == NULL) { perror("malloc failure\n"); exit(-1); } buf = (unsigned char *) (((unsigned long)xbuf + BUF_MASK) & ~BUF_MASK); /* Build HTTP Get Request */ n = snprintf(post, HTTP_POST_SIZE, "GET /%s HTTP/1.1\r\n" "Host: %s:%d\r\n" "Rate: %d\r\n" "PlaySpeed.dlna.org: speed=1\r\n" "User-Agent: %s Test App\r\n" "\r\n", fname, server, port, maxrate, "STDSOCKET" ); printf("Sending HTTP Request:----->[\n%s]\n", post); /* open file for writing */ if (!dont_write_to_disk) { p=strrchr(fname,'/'); fname=p+1; fp = fopen(fname,"wb"); if (!fp) { perror("File open error:\n"); exit(-1); } } /*TODO: enable O_DIRECT and test, need to change BUF_SIZE*/ /*fcntl(fileno(fp),F_SETFL,O_DIRECT);*/ /* Connect to Server */ sd = TcpConnect(server, port,  SOCK_STREAM); if (sd < 0) { printf("Connection to Server Failed, Exiting...\n"); exit(-1); } /* Send HTTP Get Request */ n = write(sd, post, strlen(post)); if ((unsigned)n != strlen(post)) { printf("Failed to write HTTP Get Request: rc %d\n", n); perror("write(): "); exit(-1); } printf("Succesfully Send HTTP Get Request to to %s:%d\n", server, port); usleep(10000); /* Read HTTP Response */ memset(rbuf, 0, 1024); if ( (n = read(sd, rbuf, 1024)) <= 0) { printf("Failed to read HTTP Response: rc = %d\n", n); perror("read(): "); exit(-1); }     rbuf[n] = '\0';  /* Scan for end of HTTP header */ p = strstr(rbuf,"\r\n\r\n"); if(!p) { printf("No HTTP Header\n"); len = 0; p = rbuf; tok = 0; } else { p+=4; tok = *p; *p = 0; len = strlen(rbuf); } printf("Total response len %d, payload len %d\n", n, n-len); printf("HTTP Response: -----> [\n%s]\n", rbuf); *p = tok; /* write any data that was read part of the initial read */ if (n>len) { if ( (total = write(fileno(fp), p, n - len)) <= 0 ) { printf("Failed to write initial payload bytes (%lu)\n", total); perror("write():\n"); exit(-1); } } /* increase the recv buffer before starting to read the content */ //sockSetRecvParams(sd, accel_socket); sleep(1); gettimeofday(&start, NULL); /* read data from network & write to the file */ while(1) { if ( (n = read(sd, buf, BUF_SIZE)) <= 0) { gettimeofday(&stop, NULL); printf("read failed: n = %d\n", n); perror("read(): "); break; } gettimeofday(&stop, NULL); if (dont_write_to_disk) {             bytes = n; goto after_write;         } if (((bytes = write(fileno(fp), buf, n)) <= 0) || bytes != n) { printf("Failed to write payload bytes (%d)\n", bytes); perror("write():\n"); break; } after_write: dt = difftime1(&start, &stop); total += bytes; count++; if (verbose && (count % 100) == 0) { printf("[%10lu] Received %10lu Bytes in dt = %10.2fusec at rate %2.1f\n",  count, total, dt, (total * 8. / dt));   } } dt = difftime1(&start, &stop); printf("Final stats: Received %10lu bytes to %s file in %10.1fusec at %2.1f rate\n",  total, fname, dt, (total * 8. / dt)); fclose(fp); free(xbuf); free(rbuf);     free(post); return 0; } /******************************************************************************** 比如下载一个MP3文件过程如下: root@ubuntu:/home/hfl/hflsamb/network# ./http_test_client -d 192.168.1.108 -p 80 -f /myserver/wy.mp3 -v    Server 192.168.1.108, Port 80, File /myserver/wy.mp3, Maxrate 19 Sending HTTP Request:----->[ GET //myserver/wy.mp3 HTTP/1.1 Host: 192.168.1.108:80 Rate: 19 PlaySpeed.dlna.org: speed=1 User-Agent: STDSOCKET Test App ] TCP - Connection to 192.168.1.108:80 ... TCP: Connection Success Succesfully Send HTTP Get Request to to 192.168.1.108:80 Total response len 1024, payload len 773 HTTP Response: -----> [ HTTP/1.1 200 OK Date: Sun, 09 Mar 2014 10:45:55 GMT Server: Apache/2.2.22 (Win32) Last-Modified: Tue, 19 Apr 2011 13:10:17 GMT ETag: "560000000302d3-40275b-4a1453ac09c0f" Accept-Ranges: bytes Content-Length: 4204379 Content-Type: audio/mpeg ] [       100] Received    3329486 Bytes in dt = 1388794.00usec at rate 19.2 read failed: n = 0 read(): : Success Final stats: Received    4204379 bytes to wy.mp3 file in  6998282.0usec at 4.8 rate root@ubuntu:/home/hfl/hflsamb/network#  *********************************************************************************/

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2014-03-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
http服务器端工作流程
root@ubuntu:/home/hfl/hflsamb/network# ./http_test_server  -p 8000  http_test_server: port 8000,  cpu affinity CPU0, content directory /home/hfl/hflsamb/network, rate 19.400000, loop around 0, send_from_memory 0, verbose 0, disable TCP checksum 0 Allocated 4141032-bytes for buffering, # of DESC=24 Accepted Connection from 801ca8c0:51541  Read HTTP Req ( 125 bytes)[ GET //love.mp3 HTTP/1.1 Host: 192.168.28.128:8000 Rate: 19 PlaySpeed.dlna.org: speed=1 User-Agent: STDSOCKET Test App ] TokenFound = [/love.mp3] Stream file = /home/hfl/hflsamb/network//love.mp3 size=577760125939925376 HTTP Response [ HTTP/1.1 200 OK Content-Length: 2464551019266432 Connection: Keep-Alive Accept-Ranges: bytes Connection: close Content-Range: bytes 0--5224570189344358016/1 Server: Linux/2.6.18, UPnP/1.0, my test app ]Content File opened **** Reached EOF *******
用户4148957
2022/06/14
1.1K0
基于UDP的C/S模型代码实现
传输层主要应用的协议模型有两种,一种是TCP协议,另外一种则是UDP协议。TCP协议在网络通信中占主导地位,绝大多数的网络通信借助TCP协议完成数据传输。但UDP也是网络通信中不可或缺的重要通信手段。
mindtechnist
2025/03/24
700
基于UDP的C/S模型代码实现
Linux网络编程TCP
TCP/IP 协议栈是一系列网络协议(protocol)的总和,是构成网络通信的核心骨架,它定义了电子设备如何连入因特网,以及数据如何在它们之间进行传输。
DeROy
2021/11/16
5.5K0
Linux网络编程TCP
【Socket】简单的回声服务器实现
网络通信 Socket通信的3要素 通信的目的地址 使用的端口号 使用的传输层协议(如TCP、UDP) ---- Socket通信模型 简单的回声服务器实现 服务端 #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <string.h> #include <ctype.h> #include <arpa/inet.h> #define SERVER_PORT
半生瓜的blog
2023/05/13
5790
【Socket】简单的回声服务器实现
UNIX域协议(命名套接字)
这里主要介绍命名UNIX域套接字 1.什么是UNIX域套接字 Unix域协议并不是一个实际的协议族,而是在单个主机上执行客户/服务通信的一种方式。是进程间通信(IPC)的一种方式。 它提供了两类套接字:字节流套接字(有点像TCP)和数据报套接字(有点像UDP) UNIX域数据报服务是可靠的,不会丢失消息,也不会传递出错。 IP协议标识客户服务器是通过IP地址和端口号实现的,UNIX域协议中用于标识客户机和服务器的协议地址的是普通文件系统中的路径名。 2.UNIX域协议特点 1)UNIX域套接字域TCP套
xcywt
2018/01/12
3.2K1
Linux下编程获取本地IP地址的常见方法
代码编译运行平台:Linux 64bits+g++(-m64),-m64表示生成64bits的程序。
恋喵大鲤鱼
2018/08/03
8.1K0
Linux下编程获取本地IP地址的常见方法
linux网络编程之socket(七):一个进程发起多个连接和gethostbyname等函数
s1mba
2017/12/28
1.7K0
linux网络编程之socket(七):一个进程发起多个连接和gethostbyname等函数
Linux客户端网口输入转串口输出
另外,在Linux下的C语言头文件一部分不可以在Windows系统上运行,可能导致一些不便。
嘘、小点声
2020/03/19
12.7K0
linux 下经典 IO 复用模型 -- epoll 的使用
epoll 是 linux 内核为处理大批量文件描述符而对 poll 进行的改进版本,是 linux 下多路复用 IO 接口 select/poll 的增强版本,显著提高了程序在大量并发连接中只有少量活跃的情况下的CPU利用率。 在获取事件时,它无需遍历整个被侦听描述符集,只要遍历被内核 IO 事件异步唤醒而加入 ready 队列的描述符集合就行了。 epoll 除了提供 select/poll 所提供的 IO 事件的电平触发,还提供了边沿触发,,这样做可以使得用户空间程序有可能缓存 IO 状态,减少 epoll_wait 或 epoll_pwait 的调用,提高程序效率。
用户3147702
2022/06/27
7230
linux 下经典 IO 复用模型 -- epoll 的使用
epoll()函数总结
http://www.cnblogs.com/Anker/archive/2013/08/17/3263780.html
bear_fish
2018/09/20
2K0
epoll()函数总结
win32 tcp文件传输并发服务器
#include<stdio.h> #include <stdlib.h> #include <winsock2.h> #include <string.h> #pragma comment(lib,"ws2_32.lib") #define PORT 9999 #define IPADDR "127.0.0.1" #define BACKLOG 20 #define FILENAME 200 #define LENGTH 200 #define BUFFERSIZE 1024 struct F
流川疯
2019/01/18
9120
基于Socket和OpenCV的实时视频传输(On Linux)「建议收藏」
上一篇介绍了在Windows上实现基于Socket和openCV的实时视频传输,这一篇将继续讲解在Linux上的实现。
全栈程序员站长
2022/07/30
1.3K0
Linux下HTTP Server
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/109473.html原文链接:https://javaforall.cn
全栈程序员站长
2022/07/05
1.3K0
Linux网络编程之使用TCP传输文件
原创作品,转载时请务必以超链接形式标明文章原始出处:http://blog.csdn.net/gqb666/article/details/8976263,作者:gqb666
bear_fish
2018/09/20
2.8K0
poll()函数总结
http://www.cnblogs.com/Anker/archive/2013/08/15/3261006.html
bear_fish
2018/09/20
2.3K0
poll()函数总结
C语言实现http下载器(附代码)
本次给大家分享一个C语言实现http的下载器。比如做OTA升级功能时,我们能直接拿到的往往只是升级包的链接,需要我们自己去下载,这时候就需要用到http下载器。
C语言中文社区
2023/11/28
6430
C语言实现http下载器(附代码)
加密通讯协议SSL编程周立发
编译程序用下列命令: gcc -Wall ssl-client.c -o client gcc -Wall ssl-server.c -o server 运行程序用如下命令: ./server 7838 1 127.0.0.1 cacert.pem privkey.pem ./client 127.0.0.1 7838 用下面这两个命令产生上述cacert.pem和privkey.pem文件: openssl genrsa -out privkey.pem 2048 openssl req -new -x509 -key privkey.pem -out cacert.pem -days 1095 具体请参考 “OpenSSL体系下使用密钥数字证书等” 如果想对SSL有更深入的了解,请学习计算机安全相关的内容,尤其是非对称加密技术。 如果想对SSL库的源代码有深入学习,请去 www.openssl.org 下载源码来阅读。
一见
2018/08/07
1.4K0
linux网络编程之socket(十二):select函数的并发限制和 poll 函数应用举例
一、用select实现的并发服务器,能达到的并发数,受两方面限制 1、一个进程能打开的最大文件描述符限制。这可以通过调整内核参数。可以通过ulimit -n来调整或者使用setrlimit函数设置, 
s1mba
2017/12/28
1.9K0
linux网络编程之socket(十二):select函数的并发限制和 poll 函数应用举例
多路 io 转接模型 select/poll
多路io转发服务器模型也是为了解决大并发多客户端场景下的问题,比多进程、多线程开销要少。多进程多线程常规情况下都是使用 accept 或 read 函数在阻塞等接收客户端发送过来的数据,而多路io模型则是提供了一个系统函数,该函数负责阻塞判断各路被监控的文件描述符是否有数据读取或写入操作,当有数据读取或写入时再让 accept 或 read 去直接处理从而不会阻塞,系统函数可能会同时返回多个有数据的文件描述符等待后面的代码处理,所以效率上要比多进程和多线程同时只在一个位置阻塞获取数据效率要高一些,下面就介绍一下多路 io 模型 select 和 poll,poll 模型较 select 模型还存在一些优势,在本文后面将介绍。
我与梦想有个约会
2023/10/20
2730
多路 io 转接模型 select/poll
select()函数详解
http://www.cnblogs.com/Anker/archive/2013/08/14/3258674.html
bear_fish
2018/09/20
1.9K0
select()函数详解
相关推荐
http服务器端工作流程
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档