diff --git a/.vs/MyPoorWebServer/v16/.suo b/.vs/MyPoorWebServer/v16/.suo deleted file mode 100644 index 1acf9f4..0000000 Binary files a/.vs/MyPoorWebServer/v16/.suo and /dev/null differ diff --git a/.vs/MyPoorWebServer/v16/Browse.VC.db b/.vs/MyPoorWebServer/v16/Browse.VC.db deleted file mode 100644 index 138e602..0000000 Binary files a/.vs/MyPoorWebServer/v16/Browse.VC.db and /dev/null differ diff --git a/.vs/MyPoorWebServer/v16/ipch/AutoPCH/3931ba78aaa0f3f3/MAIN.ipch b/.vs/MyPoorWebServer/v16/ipch/AutoPCH/3931ba78aaa0f3f3/MAIN.ipch deleted file mode 100644 index 9bda93f..0000000 Binary files a/.vs/MyPoorWebServer/v16/ipch/AutoPCH/3931ba78aaa0f3f3/MAIN.ipch and /dev/null differ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..fe2a772 --- /dev/null +++ b/Makefile @@ -0,0 +1,7 @@ +all: myhttp + +myhttp: httpd.c + gcc -W -Wall -o myhttp httpd.c -lpthread + +clean: + rm myhttp diff --git a/MyPoorWebServer.sln b/MyPoorWebServer.sln deleted file mode 100644 index 9129b48..0000000 --- a/MyPoorWebServer.sln +++ /dev/null @@ -1,51 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.29201.188 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MyPoorWebServer", "MyPoorWebServer.vcxproj", "{36E64CF1-03B0-44E6-8B1C-698805749A75}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|ARM = Debug|ARM - Debug|ARM64 = Debug|ARM64 - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|ARM = Release|ARM - Release|ARM64 = Release|ARM64 - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {36E64CF1-03B0-44E6-8B1C-698805749A75}.Debug|ARM.ActiveCfg = Debug|ARM - {36E64CF1-03B0-44E6-8B1C-698805749A75}.Debug|ARM.Build.0 = Debug|ARM - {36E64CF1-03B0-44E6-8B1C-698805749A75}.Debug|ARM.Deploy.0 = Debug|ARM - {36E64CF1-03B0-44E6-8B1C-698805749A75}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {36E64CF1-03B0-44E6-8B1C-698805749A75}.Debug|ARM64.Build.0 = Debug|ARM64 - {36E64CF1-03B0-44E6-8B1C-698805749A75}.Debug|ARM64.Deploy.0 = Debug|ARM64 - {36E64CF1-03B0-44E6-8B1C-698805749A75}.Debug|x64.ActiveCfg = Debug|x64 - {36E64CF1-03B0-44E6-8B1C-698805749A75}.Debug|x64.Build.0 = Debug|x64 - {36E64CF1-03B0-44E6-8B1C-698805749A75}.Debug|x64.Deploy.0 = Debug|x64 - {36E64CF1-03B0-44E6-8B1C-698805749A75}.Debug|x86.ActiveCfg = Debug|x86 - {36E64CF1-03B0-44E6-8B1C-698805749A75}.Debug|x86.Build.0 = Debug|x86 - {36E64CF1-03B0-44E6-8B1C-698805749A75}.Debug|x86.Deploy.0 = Debug|x86 - {36E64CF1-03B0-44E6-8B1C-698805749A75}.Release|ARM.ActiveCfg = Release|ARM - {36E64CF1-03B0-44E6-8B1C-698805749A75}.Release|ARM.Build.0 = Release|ARM - {36E64CF1-03B0-44E6-8B1C-698805749A75}.Release|ARM.Deploy.0 = Release|ARM - {36E64CF1-03B0-44E6-8B1C-698805749A75}.Release|ARM64.ActiveCfg = Release|ARM64 - {36E64CF1-03B0-44E6-8B1C-698805749A75}.Release|ARM64.Build.0 = Release|ARM64 - {36E64CF1-03B0-44E6-8B1C-698805749A75}.Release|ARM64.Deploy.0 = Release|ARM64 - {36E64CF1-03B0-44E6-8B1C-698805749A75}.Release|x64.ActiveCfg = Release|x64 - {36E64CF1-03B0-44E6-8B1C-698805749A75}.Release|x64.Build.0 = Release|x64 - {36E64CF1-03B0-44E6-8B1C-698805749A75}.Release|x64.Deploy.0 = Release|x64 - {36E64CF1-03B0-44E6-8B1C-698805749A75}.Release|x86.ActiveCfg = Release|x86 - {36E64CF1-03B0-44E6-8B1C-698805749A75}.Release|x86.Build.0 = Release|x86 - {36E64CF1-03B0-44E6-8B1C-698805749A75}.Release|x86.Deploy.0 = Release|x86 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {04D70FF7-DC21-4578-973C-3F1CF7C68C80} - EndGlobalSection -EndGlobal diff --git a/MyPoorWebServer.vcxproj b/MyPoorWebServer.vcxproj deleted file mode 100644 index 163cf56..0000000 --- a/MyPoorWebServer.vcxproj +++ /dev/null @@ -1,85 +0,0 @@ - - - - - Debug - ARM - - - Release - ARM - - - Debug - ARM64 - - - Release - ARM64 - - - Debug - x86 - - - Release - x86 - - - Debug - x64 - - - Release - x64 - - - - {36e64cf1-03b0-44e6-8b1c-698805749a75} - Linux - MyPoorWebServer - 15.0 - Linux - 1.0 - Generic - {D51BCBC9-82E9-4017-911E-C93873C4EA2B} - - - - true - - - false - - - true - - - false - - - true - - - false - - - false - - - true - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..ca6d375 --- /dev/null +++ b/README.md @@ -0,0 +1,47 @@ +#### 1、编译准备工作 + +post.html 以及 post.cgi需要一定的权限才可以执行。 + +1、cd httpdocs + +2、sudo chmod 600 test.html + +sudo chmod 600 post.html + +sudo chmod +X post.cgi + +![](./image/1.png) + + + +3、cd ../ + +4、make + +5、 ./myhttp + + + +#### 2、资源 + +默认端口号是6379,默认是test.html界面,同一路径下还有 post.html资源 + +#### 3、整体过程图 + +![](./image/2.png) + +![](./image/3.png) + + + +![](./image/4.png) + +![](./image/5.png) + +#### 4、参考 + +非常感谢 + +https://www.cnblogs.com/qiyeboy/p/6296387.html + +https://www.jianshu.com/p/18cfd6019296 \ No newline at end of file diff --git a/httpd.c b/httpd.c new file mode 100644 index 0000000..c26b12d --- /dev/null +++ b/httpd.c @@ -0,0 +1,532 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ISspace(x) isspace((int)(x)) + + + +#define SERVER_STRING "Server: SongHao's http/0.1.0\r\n"//定义个人server名称 + + +void *accept_request(void* client); +void bad_request(int); +void cat(int, FILE *); +void cannot_execute(int); +void error_die(const char *); +void execute_cgi(int, const char *, const char *, const char *); +int get_line(int, char *, int); +void headers(int, const char *); +void not_found(int); +void serve_file(int, const char *); +int startup(u_short *); +void unimplemented(int); + + +// 处理监听到的 HTTP 请求 +void *accept_request(void* from_client) +{ + int client = *(int *)from_client; + char buf[1024]; + int numchars; + char method[255]; + char url[255]; + char path[512]; + size_t i, j; + struct stat st; + int cgi = 0; + char *query_string = NULL; + + numchars = get_line(client, buf, sizeof(buf)); + + + i = 0; + j = 0; + while (!ISspace(buf[j]) && (i < sizeof(method) - 1)) + { + //提取其中的请求方式是GET还是POST + method[i] = buf[j]; + i++; + j++; + } + method[i] = '\0'; + + if (strcasecmp(method, "GET") && strcasecmp(method, "POST")) + { + unimplemented(client); + return NULL; + } + + if (strcasecmp(method, "POST") == 0) cgi = 1; + + i = 0; + while (ISspace(buf[j]) && (j < sizeof(buf))) + j++; + + + while (!ISspace(buf[j]) && (i < sizeof(url) - 1) && (j < sizeof(buf))) + { + url[i] = buf[j]; + i++; j++; + } + url[i] = '\0'; + + + //如果是GET请求,url可能会带有?,有查询参数 + if (strcasecmp(method, "GET") == 0) + { + + query_string = url; + while ((*query_string != '?') && (*query_string != '\0')) + query_string++; + + /* 如果有?表明是动态请求, 开启cgi */ + if (*query_string == '?') + { + cgi = 1; + *query_string = '\0'; + query_string++; + }//这里感觉可以删除掉啊,好像没什么用 + + + } + + sprintf(path, "httpdocs%s", url); + + + if (path[strlen(path) - 1] == '/') + { + strcat(path, "test.html"); + + } + + if (stat(path, &st) == -1) { + while ((numchars > 0) && strcmp("\n", buf)) + numchars = get_line(client, buf, sizeof(buf)); + + not_found(client); + } + else + { + + + if ((st.st_mode & S_IFMT) == S_IFDIR)//S_IFDIR代表目录 + //如果请求参数为目录, 自动打开test.html + { + strcat(path, "/test.html"); + } + + //文件可执行 + if ((st.st_mode & S_IXUSR) || + (st.st_mode & S_IXGRP) || + (st.st_mode & S_IXOTH)) + //S_IXUSR:文件所有者具可执行权限 + //S_IXGRP:用户组具可执行权限 + //S_IXOTH:其他用户具可读取权限 + cgi = 1; + //这一点感觉也没什么用啊 + + if (!cgi) + + serve_file(client, path); + else + execute_cgi(client, path, method, query_string); + + } + + close(client); + //printf("connection close....client: %d \n",client); + return NULL; +} + + + +void bad_request(int client) +{ + char buf[1024]; + //发送400 + sprintf(buf, "HTTP/1.0 400 BAD REQUEST\r\n"); + send(client, buf, sizeof(buf), 0); + sprintf(buf, "Content-type: text/html\r\n"); + send(client, buf, sizeof(buf), 0); + sprintf(buf, "\r\n"); + send(client, buf, sizeof(buf), 0); + sprintf(buf, "

Your browser sent a bad request, "); + send(client, buf, sizeof(buf), 0); + sprintf(buf, "such as a POST without a Content-Length.\r\n"); + send(client, buf, sizeof(buf), 0); +} + + +void cat(int client, FILE *resource) +{ + //发送文件的内容 + char buf[1024]; + fgets(buf, sizeof(buf), resource); + while (!feof(resource)) + { + + send(client, buf, strlen(buf), 0); + fgets(buf, sizeof(buf), resource); + } +} + + +void cannot_execute(int client) +{ + char buf[1024]; + //发送500 + sprintf(buf, "HTTP/1.0 500 Internal Server Error\r\n"); + send(client, buf, strlen(buf), 0); + sprintf(buf, "Content-type: text/html\r\n"); + send(client, buf, strlen(buf), 0); + sprintf(buf, "\r\n"); + send(client, buf, strlen(buf), 0); + sprintf(buf, "

Error prohibited CGI execution.\r\n"); + send(client, buf, strlen(buf), 0); +} + + +void error_die(const char *sc) +{ + perror(sc); + exit(1); +} + + +//执行cgi动态解析 +void execute_cgi(int client, const char *path, + const char *method, const char *query_string) +{ + + + char buf[1024]; + int cgi_output[2]; + int cgi_input[2]; + + pid_t pid; + int status; + + int i; + char c; + + int numchars = 1; + int content_length = -1; + //默认字符 + buf[0] = 'A'; + buf[1] = '\0'; + if (strcasecmp(method, "GET") == 0) + + while ((numchars > 0) && strcmp("\n", buf)) + { + numchars = get_line(client, buf, sizeof(buf)); + }//这里感觉也可以不要 + else + { + + numchars = get_line(client, buf, sizeof(buf)); + while ((numchars > 0) && strcmp("\n", buf)) + { + buf[15] = '\0'; + if (strcasecmp(buf, "Content-Length:") == 0) + content_length = atoi(&(buf[16])); + + numchars = get_line(client, buf, sizeof(buf)); + } + + if (content_length == -1) { + bad_request(client); + return; + } + } + + + sprintf(buf, "HTTP/1.0 200 OK\r\n"); + send(client, buf, strlen(buf), 0); + if (pipe(cgi_output) < 0) { + cannot_execute(client); + return; + } + if (pipe(cgi_input) < 0) { + cannot_execute(client); + return; + } + + if ( (pid = fork()) < 0 ) { + cannot_execute(client); + return; + } + if (pid == 0) /* 子进程: 运行CGI 脚本 */ + { + char meth_env[255]; + char query_env[255]; + char length_env[255]; + + dup2(cgi_output[1], 1); + dup2(cgi_input[0], 0); + + + close(cgi_output[0]);//关闭了cgi_output中的读通道 + close(cgi_input[1]);//关闭了cgi_input中的写通道 + + + sprintf(meth_env, "REQUEST_METHOD=%s", method); + putenv(meth_env); + + if (strcasecmp(method, "GET") == 0) { + //存储QUERY_STRING + sprintf(query_env, "QUERY_STRING=%s", query_string); + putenv(query_env); + } + else { /* POST */ + //存储CONTENT_LENGTH + sprintf(length_env, "CONTENT_LENGTH=%d", content_length); + putenv(length_env); + } + + + execl(path, path, NULL);//执行CGI脚本 + exit(0); + } + else { + close(cgi_output[1]); + close(cgi_input[0]); + if (strcasecmp(method, "POST") == 0) + + for (i = 0; i < content_length; i++) + { + + recv(client, &c, 1, 0); + + write(cgi_input[1], &c, 1); + } + + + + //读取cgi脚本返回数据 + + while (read(cgi_output[0], &c, 1) > 0) + //发送给浏览器 + { + send(client, &c, 1, 0); + } + + //运行结束关闭 + close(cgi_output[0]); + close(cgi_input[1]); + + + waitpid(pid, &status, 0); + } +} + + +//解析一行http报文 +int get_line(int sock, char *buf, int size) +{ + int i = 0; + char c = '\0'; + int n; + + while ((i < size - 1) && (c != '\n')) + { + n = recv(sock, &c, 1, 0); + + if (n > 0) // 读到数据了 + { + if (c == '\r')//判断是不是读到末尾 也就是 \r \n了 + { + + n = recv(sock, &c, 1, MSG_PEEK);// 读来看看,并没有从缓冲区把数据读出来 + if ((n > 0) && (c == '\n'))//有的好像是 \r\n 不管了,我们只认为\r\n就到达末尾了 + recv(sock, &c, 1, 0); + else + c = '\n'; + } + buf[i] = c; + i++; + + } + else + c = '\n'; + } + buf[i] = '\0'; + return(i); +} + + +void headers(int client, const char *filename) +{ + + char buf[1024]; + + (void)filename; /* could use filename to determine file type */ + //发送HTTP头 + strcpy(buf, "HTTP/1.0 200 OK\r\n"); + send(client, buf, strlen(buf), 0); + strcpy(buf, SERVER_STRING); + send(client, buf, strlen(buf), 0); + sprintf(buf, "Content-Type: text/html\r\n"); + send(client, buf, strlen(buf), 0); + strcpy(buf, "\r\n"); + send(client, buf, strlen(buf), 0); + +} + + +void not_found(int client) +{ + char buf[1024]; + //返回404 + sprintf(buf, "HTTP/1.0 404 NOT FOUND\r\n"); + send(client, buf, strlen(buf), 0); + sprintf(buf, SERVER_STRING); + send(client, buf, strlen(buf), 0); + sprintf(buf, "Content-Type: text/html\r\n"); + send(client, buf, strlen(buf), 0); + sprintf(buf, "\r\n"); + send(client, buf, strlen(buf), 0); + sprintf(buf, "Not Found\r\n"); + send(client, buf, strlen(buf), 0); + sprintf(buf, "

The server could not fulfill\r\n"); + send(client, buf, strlen(buf), 0); + sprintf(buf, "your request because the resource specified\r\n"); + send(client, buf, strlen(buf), 0); + sprintf(buf, "is unavailable or nonexistent.\r\n"); + send(client, buf, strlen(buf), 0); + sprintf(buf, "\r\n"); + send(client, buf, strlen(buf), 0); +} + + +//如果不是CGI文件,也就是静态文件,直接读取文件返回给请求的http客户端 +void serve_file(int client, const char *filename) +{ + FILE *resource = NULL; + int numchars = 1; + char buf[1024]; + buf[0] = 'A'; + buf[1] = '\0';//这个赋值不清楚是干什么的 + while ((numchars > 0) && strcmp("\n", buf)) //将HTTP请求头读取并丢弃 + { + numchars = get_line(client, buf, sizeof(buf)); + } + + //打开文件 + resource = fopen(filename, "r"); + if (resource == NULL) + //如果文件不存在,则返回not_found + not_found(client); + else + { + //添加HTTP头 + headers(client, filename); + //并发送文件内容 + cat(client, resource); + } + fclose(resource);//关闭文件句柄 +} + +//启动服务端 +int startup(u_short *port) //初始化 httpd 服务,包括建立套接字,绑定端口,进行监听等。 +{ + int httpd = 0,option; + struct sockaddr_in name; + //设置http socket + httpd = socket(PF_INET, SOCK_STREAM, 0);//创建一个套接字,采用TCP流进行连接 + if (httpd == -1) + error_die("socket");//连接失败 + + socklen_t optlen; + optlen = sizeof(option); + option = 1; + setsockopt(httpd, SOL_SOCKET, SO_REUSEADDR, (void *)&option, optlen); + + + memset(&name, 0, sizeof(name)); + name.sin_family = AF_INET;//地址族 + name.sin_port = htons(*port);//16位TCP端口号 + name.sin_addr.s_addr = htonl(INADDR_ANY);//32位IP地址 + //绑定端口 + if (bind(httpd, (struct sockaddr *)&name, sizeof(name)) < 0) + error_die("bind");//绑定失败 + if (*port == 0) /*动态分配一个端口 */ + { + socklen_t namelen = sizeof(name); + if (getsockname(httpd, (struct sockaddr *)&name, &namelen) == -1) + error_die("getsockname"); + *port = ntohs(name.sin_port); + } + //监听连接 + if (listen(httpd, 5) < 0) + error_die("listen"); + return(httpd); +} + + +void unimplemented(int client) +{ + char buf[1024]; + //发送501说明相应方法没有实现 + sprintf(buf, "HTTP/1.0 501 Method Not Implemented\r\n"); + send(client, buf, strlen(buf), 0); + sprintf(buf, SERVER_STRING); + send(client, buf, strlen(buf), 0); + sprintf(buf, "Content-Type: text/html\r\n"); + send(client, buf, strlen(buf), 0); + sprintf(buf, "\r\n"); + send(client, buf, strlen(buf), 0); + sprintf(buf, "Method Not Implemented\r\n"); + send(client, buf, strlen(buf), 0); + sprintf(buf, "\r\n"); + send(client, buf, strlen(buf), 0); + sprintf(buf, "

HTTP request method not supported.\r\n"); + send(client, buf, strlen(buf), 0); + sprintf(buf, "\r\n"); + send(client, buf, strlen(buf), 0); +} + +/**********************************************************************/ + +int main(void) +{ + int server_sock = -1; + u_short port = 6379;//默认监听端口号 port 为6379 + int client_sock = -1; + struct sockaddr_in client_name; + socklen_t client_name_len = sizeof(client_name); + pthread_t newthread; + server_sock = startup(&port); + + printf("http server_sock is %d\n", server_sock); + printf("http running on port %d\n", port); + //采用多线程处理HTTP请求 + while (1) + { + //通过accept接受客户端连接,等待socket建立连接,采用的是阻塞方式 + client_sock = accept(server_sock, + (struct sockaddr *)&client_name, + &client_name_len); + + printf("New connection.... ip: %s , port: %d\n",inet_ntoa(client_name.sin_addr),ntohs(client_name.sin_port)); + if (client_sock == -1) + error_die("accept"); + //启动线程处理新的连接 + if (pthread_create(&newthread , NULL, accept_request, (void*)&client_sock) != 0)//创建新线程 + perror("pthread_create"); + + } + close(server_sock); + + return(0); +} diff --git a/httpdocs/post.cgi b/httpdocs/post.cgi new file mode 100644 index 0000000..9346b9c --- /dev/null +++ b/httpdocs/post.cgi @@ -0,0 +1,27 @@ +#!/usr/bin/python +#coding:utf-8 +import sys,os +import urllib +length = os.getenv('CONTENT_LENGTH') + +if length: + postdata = sys.stdin.read(int(length)) + print "Content-type:text/html\n" + print '' + print '' + print 'POST' + print '' + print '' + print '

Your POST data:

' + print '
    ' + for data in postdata.split('&'): + print '
  • '+data+'
  • ' + print '
' + print '' + print '' + +else: + print "Content-type:text/html\n" + print 'no found' + + diff --git a/httpdocs/post.html b/httpdocs/post.html new file mode 100644 index 0000000..bfaf221 --- /dev/null +++ b/httpdocs/post.html @@ -0,0 +1,40 @@ + + + + 注册信息 + + + +
+ 账号: +
+
+ 密码: +
+
+ 爱好:体育唱歌 +
+
+ 性别:女 +
+
+ 自我介绍:
+ +
+
+ 地址: + +
+
+ + +
+ + diff --git a/httpdocs/test.html b/httpdocs/test.html new file mode 100644 index 0000000..4d9eb76 --- /dev/null +++ b/httpdocs/test.html @@ -0,0 +1,12 @@ + +Test + + + + + +

Hello,My name is Song Hao, i am testing~ this is my little webserver. + + + + diff --git a/image/1-1.png b/image/1-1.png new file mode 100644 index 0000000..00d5870 Binary files /dev/null and b/image/1-1.png differ diff --git a/image/1.png b/image/1.png new file mode 100644 index 0000000..f74920f Binary files /dev/null and b/image/1.png differ diff --git a/image/2.png b/image/2.png new file mode 100644 index 0000000..cbc4d01 Binary files /dev/null and b/image/2.png differ diff --git a/image/3.png b/image/3.png new file mode 100644 index 0000000..ff646b6 Binary files /dev/null and b/image/3.png differ diff --git a/image/4.png b/image/4.png new file mode 100644 index 0000000..7845229 Binary files /dev/null and b/image/4.png differ diff --git a/image/5.png b/image/5.png new file mode 100644 index 0000000..499e037 Binary files /dev/null and b/image/5.png differ diff --git a/main.cpp b/main.cpp deleted file mode 100644 index a37e3bd..0000000 --- a/main.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#include - -int main() -{ - - printf("hello from MyPoorWebServer!\n"); - return 0; -} \ No newline at end of file diff --git a/myhttp.png b/myhttp.png new file mode 100644 index 0000000..9d1a20d Binary files /dev/null and b/myhttp.png differ diff --git a/readme/images/ArchOptions.gif b/readme/images/ArchOptions.gif deleted file mode 100644 index 1ac4891..0000000 Binary files a/readme/images/ArchOptions.gif and /dev/null differ diff --git a/readme/images/ChangeRemote.gif b/readme/images/ChangeRemote.gif deleted file mode 100644 index 0de4274..0000000 Binary files a/readme/images/ChangeRemote.gif and /dev/null differ diff --git a/readme/images/ManageConnections.gif b/readme/images/ManageConnections.gif deleted file mode 100644 index be6ee98..0000000 Binary files a/readme/images/ManageConnections.gif and /dev/null differ diff --git a/readme/images/OutputTypes.gif b/readme/images/OutputTypes.gif deleted file mode 100644 index 41ccb08..0000000 Binary files a/readme/images/OutputTypes.gif and /dev/null differ diff --git a/readme/images/debuggerexport.png b/readme/images/debuggerexport.png deleted file mode 100644 index 6579d86..0000000 Binary files a/readme/images/debuggerexport.png and /dev/null differ diff --git a/readme/images/firstconnection.png b/readme/images/firstconnection.png deleted file mode 100644 index 71c3591..0000000 Binary files a/readme/images/firstconnection.png and /dev/null differ diff --git a/readme/images/linker.png b/readme/images/linker.png deleted file mode 100644 index ec67688..0000000 Binary files a/readme/images/linker.png and /dev/null differ diff --git a/readme/images/postbuild.png b/readme/images/postbuild.png deleted file mode 100644 index 09a6a77..0000000 Binary files a/readme/images/postbuild.png and /dev/null differ diff --git a/readme/readme.html b/readme/readme.html deleted file mode 100644 index 212d238..0000000 --- a/readme/readme.html +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - - - Getting Started - - - - -

- - - - -
- -
- - - -
-
-

Setting up your project for Linux Development

- -

With this workload you can author C++ code for Linux servers, desktops and devices. You can manage your connections to these machines from within VS. VS will automatically copy and remotely build your sources and can launch your application with the debugger. Our project system supports targeting specific architectures, including ARM.

- - -

Connecting to Linux

-

Prerequisites

-

Today we only support building remotely on the Linux target machine. We are not limited by specific Linux distros but we do have dependencies on the presence of some tools. Specifically, we need openssh-server, g++, gdb and gdbserver. Use your favorite package manager to install them, e.g. on Debian based systems: sudo apt-get install openssh-server g++ gdb gdbserver

- -

First connection

-

The first time you target a Linux machine you will be prompted for connection information. This is triggered by building the project.

- - -

Adding and removing connections

-

To add a new connection, go to Tools > Options and search for Connection, Connection Manager will be under Cross Platform. From here you can add and remove connections.

- - -

To change which connection a project is using go to the project properties general settings and update the Remote Build Machine option.

- - -

Project Properties

-

All of the options necessary to control C++ compilation are exposed on the project properies pages. We'll cover a few specific to how things work for Linux. First under general settings, you will see the remote root is set to ~/projects/ by default and that we are setting the remote project directory to match our project name in that location.

- - -

Looking at the General settings for the project, you can see how our output and intermediate directories were configured. Additionally, you’ll see that this project was configured as an application – thus our executable is under bin/x64/Debug/ as ConsoleApplication1.out. Notice that for configuration types we also support static and dynamic libraries.

- -

Add additional library dependencies on the Linker > Input property page.

- - -

You can pass additional pre launch commands to the debugger to do things like launch graphical apps on the remote linux machine.

- - -

You can also send post build events to control remote behavior, as in this example that exports a gpio pin for use without requiring the executable run as super user.

- - -
-
-
- -

Resources

- -

Check out the VC++ for Linux Development page where we will keep updates posted and provider more in depth details on usage.

-

Give us feedback

-

Use the send feedback function in Visual Studio or contact us directly at VC++ Linux Support

-
-
-
- - diff --git a/readme/stylesheet.css b/readme/stylesheet.css deleted file mode 100644 index eb851aa..0000000 --- a/readme/stylesheet.css +++ /dev/null @@ -1,119 +0,0 @@ -body { - margin: 0; - padding: 0; - border: 0; - color: #1E1E1E; - font-size: 13px; - font-family: "Segoe UI", Helvetica, Arial, sans-serif; - line-height: 1.45; - word-wrap: break-word; -} - -/* General & 'Reset' Stuff */ - - -.container { - width: 1100px; - margin: 0 auto; -} - -section { - display: block; - margin: 0; -} - -h1, h2, h3, h4, h5, h6 { - margin: 0; -} - -table, tr { - width: 1100px; - padding: 0px; - vertical-align: top; - } - -/* Header,
- header - container - h1 - project name - h2 - project description -*/ - -#header { - color: #FFF; - background: #68217a; - position:relative; -} -h1, h2 { - font-family: "Segoe UI Light", "Segoe UI", Helvetica, Arial, sans-serif; - line-height: 1; - margin: 0 18px;; - padding: 0; -} -#header h1 { - font-size: 3.4em; - padding-top: 18px; - font-weight: normal; - margin-left: 15px; -} - -#header h2 { - font-size: 1.5em; - margin-top: 10px; - padding-bottom: 18px; - font-weight: normal; -} - -#main_content { - width: 100%; - display: flex; - flex-direction: row; -} - - -h1, h2, h3, h4, h5, h6 { - font-weight: bolder; -} - -#main_content h1 { - font-size: 1.8em; - margin-top: 34px; -} - - #main_content h1:first-child { - margin-top: 30px; - } - -#main_content h2 { - font-size: 1.8em; -} -p, ul { - margin: 11px 18px; -} - -#main_content a { - color: #06C; - text-decoration: none; -} -ul { - margin-top: 13px; - margin-left: 18px; - padding-left: 0; -} - ul li { - margin-left: 18px; - padding-left: 0; - } -#lpanel { - width: 870px; - float: left; -} -#rpanel ul { - list-style-type: none; -} - #rpanel ul li { - line-height: 1.8em; - } -#rpanel { - background: #e7e7e7; - width: 230px; -}