- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我一直致力于创建一个小型 C 服务器,浏览器可以连接该服务器并对文件发出“GET”请求。我使用典型的“套接字”、“绑定(bind)”、“监听”和“接受”运行服务器的基本结构。然后我使用文件描述符“accept”来调用对客户端的“write”或“send”调用,这会以以下形式发出“GET”请求
http://ip_address:port/request
我采取的第一步是读取accept_fd(由accept返回)并获取它的第一行,即“GET/request HTTP/1.1\r\n”。然后我用它来创建适当的 HTTP header 来发送文件。
GET /image_file.gif HTTP/1.1\r\n
\r\n
HTTP/1.1 200 OK\r\n
Content-Type: image.gif\r\n
Content-Length: 9184\r\n
\r\n
内容长度是从文件统计信息的 st_size 中获取的,并且与我想要发送的文件相对应,所以这告诉我我正在处理正确的文件。我使用“fopen”和“r”来读取内容,并将“fread”的内容存储到我制作的大字符数组中。最后,我使用“发送”发送了存储文件内容的缓冲区,客户端浏览器接收了它,但显示的内容是一些无法识别的字符(可能是二进制)的乱码。
GIF89awÄ��ëQiò‹›òŒ›øÅÍìRiæ&Cýðòîn‚õ¨´éC\úÓÙè4Pûâæó™§í`uð}Žö¶Àõ©
这是浏览器上的片段,而不是图像文件。我已经尝试解决这个问题四天了,并尝试了各种方法,例如单独发送 HTTP header 的每个部分而不是一次全部发送,使用“fgetc”和“write”一次发送一个字节的图像文件,但是这些尝试都没有成功。我发送图像文件的操作有问题吗? (还有 html 文件。当我尝试发送它时,所有标签都显示为文本文件,而不是浏览器解释和格式化页面。)
#include <arpa/inet.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#define STAT_200 " 200 OK\r\n"
#define STAT_404 " 404 Not Found\r\n"
#define STAT_501 " 501 Not Implemented\r\n"
#define F_DIR "Content-Type: text/directory\r\n"
#define F_GIF "Content-Type: image/gif\r\n"
#define F_HTML "Content-Type: text/html\r\n"
#define F_JPEG "Content-Type: image/jpeg\r\n"
#define F_JPG "Content-Type: image/jpg\r\n"
#define F_TXT "Content-Type: text/plain\r\n"
typedef enum {cgi, gif, html, jpeg, jpg, plain} ext;
ext get_ext(char *file) {
if (strstr(file, ".cgi") != NULL)
return cgi;
if (strstr(file, ".gif") != NULL)
return gif;
if (strstr(file, ".html") != NULL)
return html;
if (strstr(file, ".jpeg") != NULL)
return jpeg;
if (strstr(file, ".jpg") != NULL)
return jpg;
if (strstr(file, ".txt") != NULL)
return plain;
}
void parse(int accept_fd) {
char *response = (char *) malloc(sizeof(char) * 512);
char *content = (char *) malloc(sizeof(char) * 512);
if (read(accept_fd, content, 512) < 0) {
perror("read error");
exit(1);
}
char *part_end = strstr(content, "\n");
*(part_end + 1) = 0; // still has \r\n
strcat(response, content);
strcat(response, "\r\n");
// send(accept_fd, content, strlen(content), MSG_CONFIRM);
// send(accept_fd, "\r\n", 2, MSG_CONFIRM); // empty line
*(part_end - 1) = 0; // no more \r\n
char *type = (char *) malloc(sizeof(char) * 256); // "GET"
char *request = (char *) malloc(sizeof(char) * 256); // "/request"
char *version = (char *) malloc(sizeof(char) * 256); // "HTTP/x.x"
strcpy(type, content);
strcpy(request, strstr(content, "/"));
strcpy(version, strstr(content, "HTTP"));
part_end = strstr(type, "/");
*(part_end - 1) = 0;
part_end = strstr(request, "HTTP");
*(part_end - 1) = 0;
strcat(response, version);
// send(accept_fd, version, strlen(version), MSG_CONFIRM); // write the "HTTP/x.x"
if (strcmp(type, "GET") != 0) { // 501
strcat(response, STAT_501);
// send(accept_fd, STAT_501, strlen(STAT_501), MSG_CONFIRM);
}
struct stat f_stat;
int stat_fd;
char *cwd = (char *) malloc(sizeof(char) * 256);
char *f_name = (char *) malloc(sizeof(char) * 256);
if ((cwd = getcwd(cwd, 256)) == NULL) {
perror("getcwd error");
exit(1);
}
strcpy(f_name, cwd);
strcat(f_name, request);
if ((stat_fd = stat(f_name, &f_stat)) < 0) { // 404
strcat(response, STAT_404);
// send(accept_fd, STAT_404, strlen(STAT_404), MSG_CONFIRM);
}
if S_ISDIR(f_stat.st_mode) { // 200
strcat(response, STAT_200);
strcat(response, F_DIR);
strcat(response, "\r\n");
// send(accept_fd, STAT_200, strlen(STAT_200), MSG_CONFIRM); // # stat
// send(accept_fd, "Content-Type: text/directory\r\n", 30, MSG_CONFIRM);
// send(accept_fd, "\r\n", 2, MSG_CONFIRM);
write(accept_fd, response, strlen(response));
int red;
if ((red = dup2(accept_fd, STDOUT_FILENO)) < 0) {
perror("dup error");
exit(1);
}
if (execlp("ls", "ls", f_name, NULL) < 0) {
perror("exec error");
exit(1);
}
close(accept_fd);
exit(0);
} else if S_ISREG(f_stat.st_mode) { // 200
strcat(response, STAT_200);
// send(accept_fd, STAT_200, strlen(STAT_200), MSG_CONFIRM); // # stat
ext f_ext = get_ext(f_name);
if (f_ext == cgi) {
int red;
if ((red = dup2(accept_fd, STDOUT_FILENO)) < 0) {
perror("dup error");
exit(1);
}
if (execlp(f_name, f_name, NULL) < 0) {
perror("exec family error");
exit(1);
}
close(accept_fd);
exit(0);
} else if (f_ext == gif) {
strcat(response, F_GIF);
// send(accept_fd, F_GIF, strlen(F_GIF), MSG_CONFIRM);
FILE *f_open;
char *f_cont = (char *) malloc(sizeof(char) * 524288);
size_t f_size = f_stat.st_size;
char *con_len = (char *) malloc(sizeof(char) * 64);
sprintf(con_len, "Content-Length: %d\r\n\r\n", (int) f_size);
strcat(response, con_len);
write(accept_fd, response, strlen(response));
// send(accept_fd, con_len, strlen(con_len), MSG_CONFIRM); // Content-length: #\r\n
if ((f_open = fopen(f_name, "r")) == NULL) {
perror("fopen error");
exit(1);
}
// int i;
// char ch;
// for (i = 0; i < f_size; i++) {
// ch = fgetc(f_open);
// send(accept_fd, &ch, 1, MSG_CONFIRM);
// }
fread(f_cont, sizeof(char), f_size, f_open);
send(accept_fd, f_cont, f_size, MSG_CONFIRM);
close(accept_fd);
exit(0);
}
这是代码的相关部分,我通过检查字符串长度反复检查是否漏掉了 header 中的\r 或\n,但效果不佳。有这方面经验的人,能指出错误在哪里吗?我是否在任何地方滥用了任何功能?我去掉了它发送 html 文件的部分,因为它之前失败了,所以我主要致力于传输 gif 文件。
最佳答案
事实证明,标题应该从我认为正确的标题的第三行开始。所以它应该看起来像这样:
HTTP/1.1 200 OK\r\n
Content-Type: text/html\r\n
\r\n
[file content]
关于html - 浏览器将C服务器发送过来的图像文件显示为一长串字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23359649/
谁能解释一下 Server.MapPath(".")、Server.MapPath("~")、Server.MapPath(@"之间的区别\") 和 Server.MapPath("/")? 最佳答案
我不知道,为什么我们要使用 Server.UrlEncode() & Server.UrlDecode()?!在 QueryString 中我们看到 URL 中的任何内容,那么为什么我们要对它们进行编
我已经通过 WHM 在我的一个域上安装了 ssl 证书。网站正在使用 https://xyz.com . 但是它不适用于 https://www.xyz.com .我已经检查了证书,它也适用于 www
我已经使用 WMI 检测操作系统上是否存在防病毒软件,itz 正常工作并通过使用命名空间向我显示防病毒信息,例如 win xp 和 window7 上的名称和实例 ID:\root\SecurityC
我们有 hive 0.10 版本,我们想知道是否应该使用 Hive Server 1 或 Hive Server2。另一个问题是连接到在端口 10000 上运行的 Hive 服务器,使用 3rd 方工
我想在 C++ 中使用 Windows Server API 设置一个 HTTPS 服务器,我使用了示例代码,它在 HTTP 上工作正常,但我就是不能让它在 HTTPS 上工作。 (我不想要客户端 S
我写了一个非常基本的类来发送电子邮件。我用 smtp 服务器对其进行了测试,它工作正常,但是当我尝试使用我公司的交换服务器时,它给出了这个异常: SMTP 服务器需要安全连接或客户端未通过身份验证。服
我的应用程序包含一个“网关”DataSnap REST 服务器,它是所有客户端的第一个访问点。根据客户端在请求中传递的用户名(基本身份验证),请求需要重定向到另一个 DataSnap 服务器。我的问题
我有一个 Tomcat 服务器和一个 Glassfish4 服务器。我的 Servlet 在 Tomcat 服务器上启动得很好,但在 Glassfish4 服务器上给我一个“HTTP Status 4
我在 vmware 上创建了一个 ubuntu 服务器。我用它作为文件服务器。如果我通过托管虚拟机的计算机进行连接,则可以访问它。我无法从同一网络上的其他计算机执行此操作。提前致谢! 最佳答案 首先确
如何重启 Rails 服务器?我从 开始 rails server -d 所以服务器是分离的 我知道的唯一方法就是去做ps 辅助 | grep rails 并 kill -9关于过程#但是像这样杀死进
我实际上正在尝试找到编写一个简单的 XMPP 服务器的最佳方法,或者找到一个占用空间非常小的服务器。我只关心XMPP的核心功能(状态、消息传递、群组消息传递)。目前还在学习 XMPP 协议(proto
我实际上正在尝试找到编写简单 XMPP 服务器的最佳方法,或者找到一个占用空间非常小的方法。我只关心 XMPP 的核心功能(统计、消息、组消息)。目前也在学习 XMPP 协议(protocol),所以
我们正在尝试从 Java JAX-RS 适配器访问 SOAP 1.1 Web 服务。 我们正在使用从 WSDL 生成的 SOAP 客户端。 但是当解码 SOAP 故障时,我们得到以下异常: ... C
目前,我和许多其他人正在多个平台(Windows、OS X 和可能的 Linux)上使用 Python HTTP 服务器。我们正在使用 Python HTTP 服务器来测试 JavaScript 游戏
我有一个连续运行的服务器程序(C#/.NET 2.0 on Linux with mono),我想从 PHP 脚本连接到它以在网站上显示状态信息。 目的是创建一个(某种)实时浏览器游戏(无 Flash
所以我有一个单页客户端应用程序。 正常流程: 应用程序 -> OAuth2 服务器 -> 应用程序 我们有自己的 OAuth2 服务器,因此人们可以登录应用程序并获取与用户实体关联的 access_t
我们刚刚将测试 Web 服务器从 Server 2008 升级到 Server 2012 R2。我们有一个部署我们网站的批处理脚本。当它将站点推送到服务器时,它现在失败了。奇怪的是,我可以使用相同的发
建议一些加载SpagoBI服务器的方法,我尝试了所有方法来解析spagobi服务器。在 Catalina 中,错误是 - * SEVERE: Unable to process Jar entry [
当我们点击应用程序服务器(apache tomcat)时,它会创建一个线程来处理我们的请求并与 tomcat 连接,建立连接,tomcat 创建另一个线程来处理请求并将其传递给连接,连接线程将其传递给
我是一名优秀的程序员,十分优秀!