共计 4911 个字符,预计需要花费 13 分钟才能阅读完成。
文件服务器架构
职责定义
-
主线程
- 命令行输出,管理员可管制服务端工作状态
-
监听线程
- 服务端启动后对客户端连贯进行监听的工作环境
-
通信线程
- 客户端连贯胜利后与服务端的数据交互环境
主线程
int main(int argc, char *argv) | |
{if (argc >=2) {DIR *dir = opendir(argv[1]); | |
if (dir != NULL) {close(dir); | |
Run(argv[1]); | |
} | |
} | |
printf("Can not launch File Server, need a valid director as root.\n"); | |
return 0; | |
} |
if (*line) {char *cmd = FormatByChar(line, ' '); // 此处的作用次要为去除前后空格 | |
int done = 0; | |
for (i=0; i<DIM(g_handler); ++i) {if (strcmp(g_handler[i].cmd, cmd) == 0) {g_handler[i].handler(cmd); | |
done = 1; | |
break; | |
} | |
} | |
if (!done) {printf("\'%s\'can NOT be parser!\n", cmd); | |
} | |
free(cmd); | |
} |
交互流程一
交互流程二
监护线程
static void *Server_Thread(void *arg) | |
{while (TcpServer_IsValid(arg)) {TcpClient *client = TcpServer_Accept(arg); | |
if (client &&(g_status != PAUSE)) { | |
pthread_t tid = 0; | |
pthread_create(&tid, NULL, Process_Thread, client); | |
} else {TcpClient_Del(client); | |
} | |
} | |
printf("%s - Thread Exit : %p\n", __FCUNTION__, arg); | |
g_status = STOP; | |
} |
申请响应流程
通信流程
static void DoResp(TcpClient *client) | |
{int len = TcpClient_Available(client); | |
if (len > 0) {char *buf = malloc(len + 1); | |
TcpClient_RecvRaw(client, buf, len); | |
buf[len] = 0; | |
char resp[255] = {0}; | |
// do process to create response | |
TcpClient_SendRaw(client, resp, strlen(resp)); | |
TcpClient_Del(client); | |
free(buff); | |
} | |
} |
编程试验:实现申请响应
main.c
#include<stdio.h> | |
#include<stdlib.h> | |
#include<unistd.h> | |
#include<pthread.h> | |
#include <sys/types.h> | |
#include <dirent.h> | |
#include <sys/stat.h> | |
#include <time.h> | |
#include <fcntl.h> | |
#include <string.h> | |
#include "tcp_server.h" | |
#include "tcp_client.h" | |
#include "utility.h" | |
#define BUF_SIZE 512 | |
typedef struct { | |
const char *cmd; | |
void (*handler)(const char *); | |
}Handler; | |
enum {STOP, RUN, PAUSE}; | |
static const volatile char *g_root = NULL; | |
static volatile int g_status = STOP; | |
static void DoResp(TcpClient *client) | |
{int len = TcpClient_Available(client); | |
if (len > 0) {char *buf = malloc(len + 1); | |
len = TcpClient_RecvRaw(client, buf, len); | |
if (len > 0) {buf[len] = 0; | |
printf("%s - Request : %s\n", __FUNCTION__, buf); | |
char resp[255] = {0}; | |
sscanf(buf, "GET %s HTTP\n", resp); // 提取文件门路!!printf("%s - Req String: %s\n", __FUNCTION__, resp); | |
char* format = "HTTP/1.1 200 OK\r\n" | |
"Server:D.T. Http Server\r\n" | |
"Content-Length:%d\r\n" | |
"Content-Type:text/html\r\n" | |
"Connection:close\r\n" | |
"\r\n" | |
"%s"; | |
sprintf(resp, format, strlen((const char*)g_root), g_root); | |
TcpClient_SendRaw(client, resp, strlen(resp)); | |
TcpClient_Del(client); | |
} | |
free(buf); | |
} | |
} | |
static void *Process_Thread(void *arg) | |
{while (TcpClient_IsValid(arg)) {DoResp(arg); | |
} | |
printf("%s - Thread Exit : %p\n", __FUNCTION__, arg); | |
return arg; | |
} | |
static void *Server_Thread(void *arg) | |
{while (TcpServer_IsValid(arg)) {TcpClient *client = TcpServer_Accept(arg); | |
if (client && (g_status != PAUSE)) { | |
pthread_t tid = 0; | |
pthread_create(&tid, NULL, Process_Thread, client); | |
} else {TcpClient_Del(client); | |
} | |
} | |
g_status = STOP; | |
return arg; | |
} | |
static void Start_Handler(const char *arg) | |
{ | |
int err = 0; | |
if (g_status == STOP) {TcpServer *server = TcpServer_New(); | |
TcpServer_Start(server, 9000, 100); | |
if (TcpServer_IsValid(server)) { | |
pthread_t tid = 0; | |
err = pthread_create(&tid, NULL, Server_Thread, server); | |
} else {err = 1;} | |
} | |
if (!err) { | |
g_status = RUN; | |
printf("Server is OK!\n"); | |
} else { | |
g_status = STOP; | |
printf("Server is failed!\n"); | |
} | |
} | |
static void Pause_Handler(const char *arg) | |
{if (g_status == RUN) { | |
g_status = PAUSE; | |
printf("Server is paused!\n"); | |
} else {printf("Server is NOT started!\n"); | |
} | |
} | |
static void Exit_Handler(const char *arg) | |
{exit(0); | |
} | |
static Handler g_handler[] = {{"start", Start_Handler}, | |
{"pause", Pause_Handler}, | |
{"exit", Exit_Handler} | |
}; | |
static void Run(const char *root) | |
{printf("File Server Demo @ D.T.Software\n"); | |
g_root = root; | |
while (1) {char line[BUF_SIZE] = {0}; | |
int i = 0; | |
printf("D.T.Software @ Input >>>"); | |
fgets(line, sizeof(line) - 1, stdin); | |
line[strlen(line) - 1] = 0; | |
if (*line) {char *cmd = FormatByChar(line, ' '); | |
int done = 0; | |
for (i-0; i<DIM(g_handler); ++i) {if (strcmp (g_handler[i].cmd, cmd) == 0) {g_handler[i].handler(cmd); | |
done = 1; | |
break; | |
} | |
} | |
if (!done) {printf("'\%s\' can NOT be parsed!\n", cmd); | |
} | |
free(cmd); | |
} | |
} | |
} | |
int main(int argc, char *argv[]) | |
{if (argc >= 2) {DIR *dir = opendir(argv[1]); | |
if (dir != NULL) {closedir(dir); | |
Run(argv[1]); | |
} | |
} | |
printf("Can not launch File Server, need a valid directory as roots.\n"); | |
return 0; | |
} |
输入:
tiansong@tiansong:~/Desktop/network/web$ ./a.out ./ | |
File Server Demo @ D.T.Software | |
D.T.Software @ Input >>> start | |
Server is OK! | |
D.T.Software @ Input >>> DoResp - Request : GET / HTTP/1.1 | |
Host: 192.168.112.165:9000 | |
Connection: keep-alive | |
Cache-Control: max-age=0 | |
Upgrade-Insecure-Requests: 1 | |
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.50 | |
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7 | |
Accept-Encoding: gzip, deflate | |
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6 | |
DoResp - Req String: /1/2/3 // 提取到的文件门路!!Process_Thread - Thread Exit : 0x7f77ac000c90 | |
DoResp - Request : GET /favicon.ico HTTP/1.1 | |
Host: 192.168.112.165:9000 | |
Connection: keep-alive | |
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.50 | |
Accept: image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8 | |
Referer: http://192.168.112.165:9000/ | |
Accept-Encoding: gzip, deflate | |
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6 | |
DoResp - Req String: /favicon.ico | |
Process_Thread - Thread Exit : 0x7f77ac000b20 |
浏览器申请
思考
favivon.ico 是什么?如何解决?
如何创立浏览器中的文件展现页面?
正文完