Http Server C语言
- 格式:docx
- 大小:17.55 KB
- 文档页数:12
C++编程笔记:使⽤WinHTTP实现HTTP访问实现HTTP访问的流程包括以下⼏步:1,⾸先我们打开⼀个Session获得⼀个HINTERNET session句柄;2,然后我们使⽤这个session句柄与服务器连接得到⼀个HINTERNET connect句柄;3,然后我们使⽤这个connect句柄来打开Http请求得到⼀个HINTERNET request句柄;4,这时我们就可以使⽤这个request句柄来发送数据与读取从服务器返回的数据;5,最后依次关闭request,connect,session句柄。
微软提供了两套http访问的接⼝:WinHTTP和WinINet。
WinHTTP⽐WinINet更加安全和健壮,可以认为WinHTTP是WinINet的升级版本。
这两套API包含了很多相似的函数与宏定义,访问的流程也是完全类似的(上述5步)。
本⽂主要通过WinHTTP实现post请求⽅法,严格按照上述5个步骤给⼤家进⾏讲解。
1 #include <iostream>2 #include <tchar.h>3 #include <string>4 #include <windows.h>5 #include <winhttp.h>6#pragma comment(lib, "winhttp.lib")78using namespace std;910int _tmain(int argc, _TCHAR* argv[])11 {12 HINTERNET hSession = NULL;13 HINTERNET hConnect = NULL;14 HINTERNET hRequest = NULL;1516//1. 初始化⼀个WinHTTP-session句柄,参数1为此句柄的名称17 hSession = WinHttpOpen(L"csdn@elaine_bao", NULL, NULL, NULL, NULL);18if (hSession == NULL) {19 cout<<"Error:Open session failed: "<<GetLastError()<<endl;20return -1;21 }2223//2. 通过上述句柄连接到服务器,需要指定服务器IP和端⼝号。
lwip1.4.0之http server实现及POST 实现一、HTTP SERVER的实现lwip默认的http server 在apps/httpserver_raw 主要核心文件为fs.c fs.h(读取相关html相关资源), httpd.c httpd.h httpd_structs.h 为http协议核心文件首先在LWIP协议栈正常运行后需要在main函数中调用httpd_init() 初始化Http 正常情况下般还需要实现SSI和CGI回调函数的初始工作本人写在一个函数中如下:void http_start(void){http_set_ssi_handler(SSIHandler, g_pcConfigSSITags, sizeof(g_pcCon figSSITags)/sizeof (char *));http_set_cgi_handlers(g_psConfigCGIURIs, sizeof(g_psConfigCGIURIs) /sizeof(tCGI));}然在httpd_init()下调用http_start() 完成初始化SSI和CGI的工作。
其次要使用makefsfile.exe 对网页进行编译这个小工具可以从网上下载一个, 本人将编译命令写在一个makefsfile.bat批处理文件中每次编译只要运行一下makefsfile.bat 具体命令如下:echo offmakefsfile -i web_pages -o ../lwip-1.4.0/src/apps/httpserver_raw/fsdata.h -r -hecho on其中web_pages为所包含的网页文件夹产生的网页数据放在fsdata.h中用于跟工程文件一起编译, -r 表示每次编译网页时重写fsdata.h -h 表示产生的网页数据中不包含http协议头部因为本人在HTTP中使用的是动态产生HTTP协议头。
简单HTTP Server的设计与实现作者:周畅王赜来源:《软件工程》2017年第01期摘要:超文本传输协议(HTTP)是分布式、协作和超媒体信息系统的应用协议。
HTTP Server是一个监听特定端口TPC连接,对客户端请求进行处理的一个应用。
得益于高级语言对HTTP协议的内置支持,我们也可以使用简单的方式来实现一个较完整功能的HTTP Server。
本文主要是研究一个HTTP Server的简单实现,在实现的过程中,能够体现出POST、GET方法,现已将要求完成,本文一共分为三个章节,分别对于此次设计进行阐述。
关键词:超文本传输协议服务;万维网;外部应用程序中图分类号:TP393.0 文献标识码:A1 引言(Introduction)CGI是WWW技术中最重要的技术之一,有着不可替代的重要地位。
CGI是外部应用程序(CGI程序)与Web服务器之间的接口标准,是在CGI程序和Web服务器之间传递信息的规程[1]。
CGI规范允许Web服务器执行外部程序,并将它们的输出发送给Web浏览器,CGI将Web的一组简单的静态超媒体文档变成一个完整的新的交互式媒体。
使在网络服务器下运行外部分应用程序(或网关)成为可能。
CGI-BIN目录是存放CGI脚本的地方。
这些脚本使Web 服务器和浏览器能运行外部程序,而无需启动另一个程序[2]。
2 项目背景(The project background)在HTTP中定义了很多和服务器之间进行交互的方法,例如平时我们所看到的GET、POST、PUT、DELETE[3,4]。
其中资源描述符是URL,在这里我们可以这样理解,一个URL地址可以描述一个网络上的资源,而前面所提到的HTTP中的,GET、POST、PUT、DELETE所对应的分别是这个资源的查、改、增、删四个操作,而这其中的POST一般适用于资源信息的更新,GET用于信息的获取/查询,因为早期的系统对于DELETE是不支持的,所以说PUT和DELETE用的比较少。
C#http服务端实例演⽰1. 创建http服务类 HttpServer.csusing System;using System.Collections.Generic;using System.Linq;using ;using System.Text;using System.Threading.Tasks;using System.Configuration;using System.Threading;using System.IO;using Entities;namespace Http_服务1{/// <summary>/// http 监听服务类/// </summary>public class HttpServer{/// <summary>/// http 监听器/// </summary>HttpListener _Listerner = null;/// <summary>/// 监听地址/// </summary>string _ListernUrl = string.Empty;/// <summary>/// 是否监听/// </summary>bool _IsRunning = false;/// <summary>/// 初始化/// </summary>public void Init(){_Listerner = new HttpListener();_IsRunning = true;if (System.Configuration.ConfigurationManager.AppSettings.AllKeys.Contains("lurl")){_ListernUrl = System.Configuration.ConfigurationManager.AppSettings["lurl"];}else{_ListernUrl = "http://127.0.0.1:1500/Service/";}}/// <summary>/// 启动服务/// </summary>public void Start(){Init();try{_Listerner.AuthenticationSchemes = AuthenticationSchemes.Anonymous;//指定⾝份验证 Anonymous匿名访问 _Listerner.Prefixes.Add(_ListernUrl);Task.Factory.StartNew(() =>{//线程池int minThreadNum;int portThreadNum;int maxThreadNum;ThreadPool.GetMaxThreads(out maxThreadNum, out portThreadNum);ThreadPool.GetMinThreads(out minThreadNum, out portThreadNum);Console.WriteLine("最⼤线程数:{0}", maxThreadNum);Console.WriteLine("最⼩空闲线程数:{0}", minThreadNum);//ThreadPool.QueueUserWorkItem(new WaitCallback(TaskProc1), x);Console.WriteLine("\n\n等待客户连接中。
HTTP1.1中CHUNKED 编码方式传输数据的解析 “隐网项目”的图片下载模块需要与HTTP Response 报文打交道,由于使用的是C++,没有java 中十分好用的httpclient ,所以打算自己实现。
之前考虑的比较简单,假设请求的文件是jpeg 文件,所以在收到数据之后,只考虑跳过响应报文的HEADER 部分加\r\n\r\n 四个字节后,直接把剩余的数据写到文件中。
测试过程中,发现有相当一部分图片不能正常打开,总是比服务器多了几个字节;打印输出响应报文后发现头中并没有我们通常所见的Content-Length 域来指明报文体的长度,反而是多了Transfer – Encoding 域。
上网查阅http1.1协议后,发现通常情况下,Transfer-Encoding 域的值应当为chunked,表明采用chunked 编码方式来进行报文体的传输。
协议中关于这个字段的具体解释如下:一般HTTP 通信时会使用是Content-Length 头信息性来指定小,但是有时候无法确定信息大小,就要使用trunked 编码动态的提供body 内容的长度。
进行Chunked 编码传输的HTTP 数据要在消息头部设置:Transfer-Encoding: chunked 表示Content Body 将用chunked 编码传输内容。
Chunked 编码一般使用若干个chunk 串连而成,最后由一个标明长度为0的chunk 标示结束。
每个chunk 分为头部和正文两部分,头部内容指定下一段正文的字符总数(非零开头的十六进制的数字)和数量单位(一般不写,表示字节).正文部分就是指定长度的实际内容,两部分之间用回车换行(CRLF)隔开。
在最后一个长度为0的chunk 中的内容是称为footer 的内容,是一些附加的Header 信息(通常可以直接忽略)。
上述解释过于官方,简而言之,chunked 编码的基本方法是将大块数据分解成多块小数据,每块都可以自指定长度,其具体格式如下:ea5 \r\n …………………………\r\n ea5 \r\n……………………………….\r\n0\r\n\r\n其C 语言的解码如下,java 思路相同int nBytes;char* pStart = a; // a中存放待解码的数据char* pT emp;char strlength[10]; //一个chunk块的长度chunk : pT emp =strstr(pStart,"\r\n");if(NULL==pTemp){free(a);a=NULL;fclose(fp);return -1;}length=pT emp-pStart;COPY_STRING(strlength,pStart,length);pStart=pT emp+2;nBytes=Hex2Int(strlength); //得到一个块的长度,并转化为十进制if(nBytes==0)//如果长度为0表明为最后一个chunk{free(a);fclose(fp);return 0;}fwrite(pStart,sizeof(char),nBytes,fp);//将nBytes长度的数据写入文件中pStart=pStart+nBytes+2; //跳过一个块的数据以及数据之后两个字节的结束符fflush(fp);goto chunk; //goto到chunk继续处理如何将一个十进制数转化为十六进制char *buf = (char *)malloc(100);char *d = buf;int shift = 0;unsigned long copy = 123445677;while (copy) {copy >>= 4;shift++;}//首先计算转化为十六进制后的位数if (shift == 0)shift++;shift <<= 2; //将位数乘于4,如果有两位的话shift为8while (shift > 0) {shift -= 4;*(buf) = hex_chars[(123445677 >> shift) & 0x0F];buf++;}*buf = '\0';。
C#⽹络编程⼊门之HTTP⼀、概述本⽂⽬的是通过C#代码提供⼀个HTTP服务,正常情况下如果我们需要向外界提供HTTP服务,常规做法就是通过来实现,有时我们的应⽤程序或Windows服务需要向外提供⼀些简单的HTTP服务就可以⾃⼰实现,从⽽避免部署IIS增加系统复杂性。
这⾥必须强调是⼀些简单的应⽤,如果应⽤⽐较复杂,涉及到路径解析HTML解析等,还是⽤WEB⽅式实现⽐较靠谱。
将HTTP和UDP、TCP放在同⼀个系列实际上有⼀点不合适,因为UDP、TCP属于传输层协议,HTTP属于应⽤层协议,希望读者⾸先有⼀个明确的了解。
⼆、提供服务⾸先启动HHTP服务:if (!HttpListener.IsSupported){Console.WriteLine("服务器操作系统不⽀持建⽴Http Server,需要更⾼版本的操作系统!");return;}HttpListener httpListener = new HttpListener();try{Console.WriteLine("正在启动Http服务");int port = 9000;httpListener.Prefixes.Add($"http://*:{port}/");httpListener.Start();Console.WriteLine("Http服务启动成功。
");}catch (Exception ex){Console.WriteLine($"启动Http服务出现异常:{ex.Message}");return;}进⾏监听:while (true){Console.WriteLine("开始监听...");HttpListenerContext context = httpListener.GetContext();HttpListenerRequest request = context.Request;string Method = request.HttpMethod.ToUpper();Console.WriteLine($"收到请求,URL:{ request.Url} Method:{Method}");Response(context, "hello");}代码循环进⾏监听,GetContext⽅法会引起阻塞,当收到浏览器请求时,服务器⽴即返回“Hello”。
c++简单实现http协议服务器和客户端C++ 简单实现HTTP GET/POST 请求HTTP(超⽂本传输协议)是⼀种客户端与服务端的传输协议,最早⽤于浏览器和服务器之间的通信,后来因为其使⽤灵活、⽅便等特点,⼴泛⽤于客户端与服务端的通信。
⽂章将简单介绍HTTP协议,同时以C++⽅式分别实现HTTP GET、POST 请求HTTP 请求报⽂HTTP请求报⽂的⼀般格式由4部分组成:请求⾏、请求头部、空⾏、请求数据。
如下图所⽰:1.jpg请求⾏:包含3部分内容:请求⽅法,URL,协议版本。
形式如:GET /?aaa=1 HTTP/1.1。
请求⽅法有GET、POST、HEAD、PUT、DELETE、OPTIONS等。
URL指请求服务端的地址,可以是相对地址或域名形式的绝对地址。
协议版本主要有HTTP/1.1 HTTP/1.0 HTTP/0.9,后⾯两种已很少使⽤了。
请求头部:以key/value形式成对表⽰头部参数,以英⽂冒号分隔。
key名称的约定写法为Key,Key-Name,⾃定义key名称⼀般以“X-”开头。
如php的声明“X-Powered-By:PHP/5.5.4-1”空⾏:⽤来标识请求头部的数据已结束。
请求数据:可选项,这块内容只在POST⽅式下使⽤,作为POST的数据表⽰区域。
使⽤这块内容,要在请求头部以Content-Length声明请求数据长度,以Content-Type声明请求数据类型。
HTTP POST请求HTTP POST⽅式是把请求参数放到HTTP请求报⽂的请求数据中,为了让例⼦更容易看懂,仅保留HTTP Post关键参数,你还可以⾃定义⼀些参数,⽐如浏览器喜欢⽤的User-Agent,Accept,Connection等等char *pHttpPost = "POST %s HTTP/1.1\r\n""Host: %s:%d\r\n""Content-Type: application/x-www-form-urlencoded\r\n""Content-Length: %d\r\n\r\n""%s";char* addr = "http://localhost/post.php";char* host = "127.0.0.1";int port = 80;char* msg = "aaa=1&bbb=2";char strHttpPost[1024] = {0};sprintf(strHttpPost, pHttpPost, addr, host, port, strlen(msg), msg);//这⾥忽略掉了socket连接代码send(sockClient, strHttpPost, strlen(strHttpPost), 0);HTTP GET请求HTTP GET⽅式是把请求参数放到HTTP请求报⽂的请求⾏URL中,所以请求⾏就是“GET /?aaa=1&bbb=2 HTTP/1.1\r\n”。
- 1 - 编号 LINUX下HTTP服务器的实现 2013~2014学年 第 二 学期
实习类别 课程设计 学生姓名 专 业 网络工程
学 号 指导教师 学 院
2014年7月10号 - 2 -
起 止 周 20~20 周 数 1 实习地点 南研1113 选 题 1 科研训练目的: 编写一个HTTP服务器,能够通过浏览器访问静态页面(页面中含有图片)以及动态页面(用C编写的程序)
课程设计要求: 项目目录里有两个文件csapp.c和csapp.h,这两个文件里的代码请认真阅读,主要是一些常用函数的包装函数(尤其是以大写字母开头的函数),在项目中请实用这两个文件里的函数。
项目目录里还有一个docs目录,这里面的内容是用来测试的,假设在浏览器中访问http://localhost:8080/docs/index.html,则需要能够显示index.html中的内容(包括图片等)。
课程设计进度安排及主要内容: (1)需求分析; (2)详细设计; (3)程序代码编写; (4)运行测试; (5)总结。
成绩:
指导教师/带队教师(签字) 年 月 日 3
摘 要
Linux操作系统是一个开放源代码的免费操作系统。它不仅有安全、稳
定、成本低的特点,而且很少发现有病毒传播。HTTP服务器是web服务器的一种,它是基于超文本传输协议HTTP的服务器。基于Linux具有稳定、可靠、安全和强大的网络功能这些优点,使得其主要应用于服务器领域。所以本文选择在Linux环境下实现一个HTTP服务器。 本文研究了Linux下HTTP服务器的设计与实现。在Linux系统中采用HTTP协议和浏览器完成数据的传输。阐述了Linux套接字编程的方法、EPOLL等I/O复用编程模型。详细分析了HTTP协议内容以及客户端与服务器之间的通信过程。本文实现了客户端浏览器和服务器端以HTTP协议进行请求和响应的功能。同时对服务器进行了一个简单的压力测试。所有程序代码均为Linux下的C语言编程。
c语⾔http⽹络编程,c语⾔socket⽹络编程本⽂收集整理关于c语⾔socket⽹络编程的相关议题,使⽤内容导航快速到达。
内容导航:Q1:linux下C语⾔⽤socket⽹络编程怎么计算传输速度?这要你的通信程序协商⼀个协议,⽐如定义⼀个通信结构体,传⽂件的时候,⼀开始发送结构体的信息过去,告诉对端你的⽂件总⼤⼩,然后,传输过程中,统计已经收到或者发送的数据,做个除法就得到速率了。
具体这类协商,你可以⾃⼰随便想,也可以借鉴现有的⽐较好的⼀些设计,有些考虑断点续传的技术,还有压缩的,看你代码也不需要考虑吧。
Q2:怎样⽤C语⾔做socket⽹络编程?mfc只是对socket进⾏了⼀些封装,⼤部分⼈做⽹络编程都是⽤的原始的socket,⽐如如下接⼝都可以在c下进⾏调⽤1.socket()2.bind()3.connect()4.listen()5.accept()6.send() 和recv()7.sendto() 和recvfrom()8.close() 和shutdown()9.getpeername()10.gethostname()这些接⼝是在Winsock2.h中定义的不是在mfc中定义的,你只需要包含Winsock2.h头⽂件和Ws2_32.lib库就可以了。
wWW.Y@Q3:请问⽤C语⾔ socket编程,如何使TCP客户端实现⽹络恢复后⾃动重连的功能?呵呵,想了想⼤概是这样⼏种可能,你可以尝试⼀下。
1。
重新连接的过程要重新创建sockclient也就是重新调⽤函数创建。
2。
服务器关闭后再开启,绑定的是同⼀个接⼝。
当关闭后再开启的时间较短时端⼝可能处于忙状态,倒置再开启绑定到该端⼝失败,也就是服务器端启动失败。
处理办法:你可以利⽤setsockopt函数,将端⼝设置为可重⽤状态,我忘记那个宏是什么了你可以上⽹去查查setsockopt的⽤法。
希望对你有⽤best wishesQ4:关于c语⾔的socket⽹络编程如果没有什么复杂的应⽤逻辑,只是⽂件传输的话, 那么建议⾸选FTP协议进⾏传输。
#include #include #include #include #include #include
#include #include #include #include #include #include
// 建立socket 开始侦听接收连接接收客户端数据解析http协议发送文件数据给客户端 #define HTTP_PORT "2010" #define MAX_CONNECTION 10 #define DOCUMENT_ROOT "www" #define LOG_PATH "log/access.log"
void parser(char *s,char res[][255],char host[][255]); static char *strtoupper( char *s ); static long filesize(const char *filename); static int file_exists(const char *filename); static void mime_content_type( const char *name, char *ret ); static int WriteLog( const char *message ); static int is_dir(const char *filename);
static unsigned short g_is_log = 1; static int g_log_fd = 0;
int main(void) { int server_sock; int client_sock; struct sockaddr_in server_addr; struct sockaddr_in client_addr; struct sockaddr_in sin; struct stat file_stat; pid_t pid; char client_ip[100]; char buf[20000]; char buf_all[2000]; char buf1[2000]; char p[3][255]; char h[3][255]; char tmp[2000]; char cwd[1024]; char filename[2000]; char filepath[2000]; int fd,size; int currentConn = 0;
DIR * dir; struct dirent * ptr;
chdir("../"); if ( (pid = fork()) < 0 ) { perror("fork"); exit(1); } else if ( pid != 0) { exit(1); }
if((server_sock = socket(AF_INET,SOCK_STREAM,0)) < 0) { perror("socket"); exit(1); }
memset(&server_addr,0,sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_port = htons(atoi(HTTP_PORT)); server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(server_sock,(struct sockaddr*)&server_addr,sizeof(server_addr)) < 0) { perror("bind"); exit(1); } if(listen(server_sock,MAX_CONNECTION) < 0) { perror("listen"); exit(1); }
printf("fasthttp successful created ...\n"); while(1) { unsigned int clientlen = sizeof(client_addr); if((client_sock = accept(server_sock,(struct sockaddr*)&client_addr,&clientlen)) < 0) { perror("accept"); exit(1); }
if((pid = fork()) == 0) {
if(read(client_sock,buf,20000) < 0) { perror("read data from client"); exit(1); }
parser(buf,p,h); if(strcmp(strtoupper(p[0]),"GET") != 0 && strcmp(strtoupper(p[0]),"POST") != 0 && strcmp(strtoupper(p[0]),"HEAD") != 0) { memset(&buf,0,sizeof(buf));
sprintf(buf, "HTTP/1.1 501 Not Implemented\r\nServer: %s\r\nContent-Type: text/html\r\nContent-Length: 1489\r\nAccept-Ranges: bytes\r\nConnection: close\r\n\r\n", "Apache"); write(client_sock,buf,strlen(buf));
memset(&buf,0,sizeof(buf)); sprintf(buf,"
WriteLog(p[1]); getcwd(filepath, sizeof(filepath)); strcat(filepath,"/"); strcat(filepath,DOCUMENT_ROOT); strcat(filepath,p[1]);
if(!file_exists(filepath)) { memset(&buf,0,sizeof(buf)); sprintf(buf, "HTTP/1.1 404 Not Found\r\nServer: %s\r\nContent-Type: text/html\r\nContent-Length: 257271\r\nConnection: close\r\n\r\n", "Apache"); write(client_sock,buf,strlen(buf));
memset(&buf,0,sizeof(buf)); sprintf(buf,"404 Not Foundbgcolor=\"white\">404 Not FoundPowered by %s","fasthttp"); write(client_sock,buf,strlen(buf)); close(client_sock);
memset(&buf,0,sizeof(buf)); sprintf(buf,"404 Not Found\t%s\n",filepath); WriteLog(buf);
exit(0); }
if(access(filepath,R_OK) < 0) { memset(&buf,0,sizeof(buf)); sprintf(buf, "HTTP/1.1 403 Forbidden\r\nServer: %s\r\nContent-Type: text/html\r\nContent-Length: 25727\r\nConnection: close\r\n\r\n", "Apache"); write(client_sock,buf,strlen(buf)); close(client_sock); exit(0); } /** 目录列表 **/ if(is_dir(filepath)) { memset(&tmp,0,sizeof(tmp)); sprintf(tmp,"Index
of %sIndex of %s Parent Directory",filepath,filepath); strcat(buf,tmp);
if((dir = opendir(filepath)) != NULL) { while((ptr = readdir(dir)) != NULL) {
if(strcmp(ptr->d_name,".") == 0 || strcmp(ptr->d_name,"..") == 0) { continue; }
memset(&buf,0,sizeof(buf)); sprintf(buf,"%s/%s",filepath,ptr->d_name);
if(is_dir(buf)) { memset(&buf,0,sizeof(buf)); sprintf(buf,"
memset(&buf,0,sizeof(buf)); sprintf(buf,"%s",""); strcat(tmp,buf);