python后端服务器_毕设里配合Python后端使用的所谓”CGI服务器“

此博客展示了一段C/C++代码,实现了后端服务器功能。代码中使用了多进程和共享内存,监听客户端连接。当有新连接时,会解析请求参数,若进程数未达上限,会fork子进程执行Python脚本;若达到上限,则返回XML响应。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.[代码][C/C++]代码

#define _GNU_SOURCE

#ifndef __GNUC__

#error FATAL

#endif

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

//for shm

#include

#include

#include

#include

#include

#include

#include

#include

#define XDEBUG

//useless ,need shared memory

size_t MAXPROCESS = 100;

pthread_mutex_t mutex;

void MAGIC(void);

void FAKE(int32_t infd, char *num, char *password, char *server);

int main(int argc, char *argv[])

{

pid_t pid;

pid_t wait;

int32_t status;

pthread_mutexattr_t mutexattr;

pthread_mutexattr_init(&mutexattr);

pthread_mutexattr_setpshared(&mutexattr,PTHREAD_PROCESS_SHARED);

//test

pthread_mutex_init(&mutex, &mutexattr);

if((pid = fork()) > 0)

exit(EXIT_SUCCESS);

else if(pid < 0)

exit(EXIT_FAILURE);

else;

if(setsid() == -1)

exit(EXIT_FAILURE);

if((pid = fork()) > 0)

exit(EXIT_SUCCESS);

else if(pid < 0)

exit(EXIT_FAILURE);

else;

if(argc == 2)

MAXPROCESS = atoi(argv[1]);

openlog(argv[0], LOG_PID | LOG_CONS, LOG_LOCAL0);

for(;;)

{

if((pid = fork()) == 0)

MAGIC();

else if(pid < 0)

exit(EXIT_FAILURE);

else;

#ifdef XDEBUG

syslog(LOG_USER | LOG_DEBUG, "MAIN Strat!");

#endif

test:

wait = waitpid(pid, &status, 0);

if(wait != pid)

goto test;

if(WIFEXITED(status))

{

if(WEXITSTATUS(status) != 0)

{

syslog(LOG_USER | LOG_ERR, "Child : %d interruped by status %d", pid, -WEXITSTATUS(status));

goto SLEEP;

}

else if(WEXITSTATUS(status) == 0)

exit(0);

else if(WIFSIGNALED(status))

{

syslog(LOG_USER | LOG_ERR, "Child : %d interruped by signal %d", pid, WTERMSIG(status));

goto SLEEP;

}

else

{

syslog(LOG_USER | LOG_ERR, "Child : %d interruped by UNKNOEN REASON", pid);

goto SLEEP;

}

}

SLEEP:

sleep(10);

}

exit(EXIT_SUCCESS);

}

void MAGIC(void)

{

struct sockaddr_in serversock, clientsock;

socklen_t clientlen = 1;//test

int32_t sockfd, acceptfd;

int32_t shmfd;

int32_t value, res;

void *pmmap;

char buffer[256] = {0};

char line[512], linea[4096], method[128], uri[256], protocol[128], num[64], pwd[64], server[6];

char *pnum, *ppwd, *ppserver;

char *numpos, *pwdpos, *serverpos;

size_t len = 0;

int flag = 0;

pid_t subpid;

if(signal(SIGCHLD, SIG_IGN) == SIG_ERR)

exit(EXIT_FAILURE);

memset(&serversock, 0, sizeof(serversock));

serversock.sin_family = AF_INET;

serversock.sin_addr.s_addr = htonl(INADDR_ANY);

serversock.sin_port = htons(getuid() ? 8080 : 80);

if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)

{

syslog(LOG_USER | LOG_ERR, "In function MAGIC:socket ---- %s", strerror(errno));

exit(-1);

}

if((setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag))) < 0)

exit(EXIT_FAILURE);

if(bind(sockfd, (struct sockaddr *)&serversock, sizeof(struct sockaddr_in)) == -1)

{

syslog(LOG_USER | LOG_ERR, "In function MAGIC:bind ---- %s", strerror(errno));

exit(EXIT_FAILURE);

}

if(listen(sockfd, 256) == -1)

{

syslog(LOG_USER | LOG_ERR, "In function MAGIC:listen ---- %s", strerror(errno));

exit(EXIT_FAILURE);

}

shmfd = shm_open("ProcessCountSHM", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);

if(shmfd < 0)

{

syslog(LOG_USER | LOG_ERR, "In function MAGIC:shm_open ---- %s", strerror(errno));

exit(EXIT_FAILURE);

}

if(ftruncate(shmfd, sizeof(int32_t)) < 0)

{

syslog(LOG_USER | LOG_ERR, "In function MAGIC:ftruncate ---- %s", strerror(errno));

exit(EXIT_FAILURE);

}

pmmap = mmap(NULL, sizeof(int32_t), PROT_READ | PROT_WRITE, MAP_SHARED, shmfd, 0);

if(pmmap == NULL)

{

syslog(LOG_USER | LOG_ERR, "In function MAGIC:mmap ---- %s", strerror(errno));

exit(EXIT_FAILURE);

}

close(shmfd);

//init shared memory

value = 0;

pthread_mutex_lock(&mutex);

memcpy(pmmap, &value, sizeof(int32_t));

pthread_mutex_unlock(&mutex);

for(;;)

{

if((acceptfd = accept(sockfd, (struct sockaddr *)&clientsock, &clientlen)) == -1)

{

syslog(LOG_USER | LOG_ERR, "In function MAGIC:accept ---- %s", strerror(errno));

exit(EXIT_FAILURE);

}

else

{

pthread_mutex_lock(&mutex);

res = *((int32_t *)pmmap);

pthread_mutex_unlock(&mutex);

#ifdef XDEBUG

syslog(LOG_USER | LOG_DEBUG, "MAGIC-IN-Accept--process_count : %d , MAXPROCESS : %zu", res, MAXPROCESS);

#endif

if(res < MAXPROCESS)

{

//do some parse then fork&exec to execute a python script

syslog(LOG_USER | LOG_INFO, "In function MAGIC:new client ---- %s", inet_ntop(AF_INET, &(clientsock.sin_addr), buffer, clientlen));

if((len = recv(acceptfd, linea, 4096, MSG_NOSIGNAL)) > 0)

{

strncpy(line, linea, (strstr(linea, "\r\n") - linea));//for request line

line[strstr(linea, "\r\n") - linea] = '\0';

sscanf(line, "%s%s%s", method, uri, protocol);

#ifdef XDEBUG

syslog(LOG_USER | LOG_DEBUG, "MAGIC:line ---- %s , %s , %s , %s", line, method, uri, protocol);

#endif

numpos = strcasestr(uri, "?num=");

pwdpos = strcasestr(uri, "&pwd=");

serverpos = strcasestr(uri, "&server=");

if(numpos == NULL || pwdpos == NULL || serverpos == NULL)//for safe

{

shutdown(acceptfd, SHUT_RDWR);

continue;

}

len = pwdpos - numpos - 5;

if(len != 11)

{

shutdown(acceptfd, SHUT_RDWR);

continue;

}

strncpy(num, numpos + 5, len);

num[len] = '\0';

if(line[strlen(line) - 1] == '/')

line[strlen(line) - 1] = '\0';

len = serverpos - pwdpos - 5;

strncpy(pwd, pwdpos + 5, len);

pwd[len] = '\0';

strncpy(server, serverpos + 8, 6);

pnum = (char *)malloc(sizeof(char) * 64);

ppwd = (char *)malloc(sizeof(char) * 64);

ppserver = (char *)malloc(sizeof(char) * 6);

strcpy(pnum, num);

strcpy(ppwd, pwd);

strcpy(ppserver, server);

//fork

if((subpid = fork()) == 0)

{

FAKE(acceptfd, pnum, ppwd, ppserver);

}

else if(subpid < 0)

{

shutdown(acceptfd, SHUT_RDWR);

free(pnum);

free(ppwd);

free(ppserver);

continue;

}

else

{

continue;

}

}

//pay attention to argument for string(LOCK)

}

else

{

//response line,response head and response body(XML)

syslog(LOG_USER | LOG_INFO, "In function MAGIC:new client ---- %s,but SERVER is full", inet_ntop(AF_INET, &(clientsock.sin_addr), buffer, clientlen));

char *responsehead = "HTTP/1.1 200 OK\r\nServer: Zirconi's\r\nContent-Type: application/xml; charset=UTF-8\r\nContent-length: " ;

char *response = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";

sprintf(buffer, "%s", responsehead);

sprintf(buffer + strlen(responsehead), "%zu\r\n\r\n", strlen(response));

strcat(buffer, response);

send(acceptfd, buffer, strlen(buffer), MSG_NOSIGNAL);//for SIGPIPE

shutdown(acceptfd, SHUT_RDWR);

}

}

}

}

void FAKE(int32_t infd, char *num, char *password, char *server)

{

char numa[64], pwda[64], servera[6];//, buffer[256];

pid_t cgi;

int32_t shmfd;

int32_t *value, res;

void *pmmap;

strcpy(numa, num);

strcpy(pwda,password);

strcpy(servera, server);

shmfd = shm_open("ProcessCountSHM", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);

if(shmfd < 0)

{

syslog(LOG_USER | LOG_ERR, "In function MAGIC:shm_open ---- %s", strerror(errno));

exit(EXIT_FAILURE);

}

if(ftruncate(shmfd, sizeof(int32_t)) < 0)

{

syslog(LOG_USER | LOG_ERR, "In function MAGIC:ftruncate ---- %s", strerror(errno));

exit(EXIT_FAILURE);

}

pmmap = mmap(NULL, sizeof(int32_t), PROT_READ | PROT_WRITE, MAP_SHARED, shmfd, 0);

if(pmmap == NULL)

{

syslog(LOG_USER | LOG_ERR, "In function MAGIC:mmap ---- %s", strerror(errno));

exit(EXIT_FAILURE);

}

close(shmfd);

pthread_mutex_lock(&mutex);

value = (int32_t *)pmmap;

pthread_mutex_unlock(&mutex);

//memcpy(pmmap, &value, sizeof(int32_t));

//need process SIGCHLD

if(signal(SIGCHLD, SIG_IGN) == SIG_ERR)

exit(EXIT_FAILURE);

#ifdef XDEBUG

syslog(LOG_USER | LOG_DEBUG, "%s ---- %s ---- %s", numa, pwda, servera);

#endif

//eat header

//while(recv(infd, buffer, 256, MSG_NOSIGNAL) != 0);

if((cgi = fork()) == 0)

{

//dup

if(dup2(infd, STDIN_FILENO) == -1)

{

#ifdef XDEBUG

syslog(LOG_USER | LOG_DEBUG, "STDIN DUP: %s", strerror(errno));

#endif

free(num);

free(password);

free(server);

munmap(pmmap, sizeof(int32_t));

exit(EXIT_FAILURE);

}

if(dup2(infd, STDOUT_FILENO) == -1)

{

#ifdef XDEBUG

syslog(LOG_USER | LOG_DEBUG, "STDOUT DUP: %s", strerror(errno));

#endif

free(num);

free(password);

free(server);

munmap(pmmap, sizeof(int32_t));

exit(EXIT_FAILURE);

}

pthread_mutex_lock(&mutex);

(*value)++;

res = *value;

pthread_mutex_unlock(&mutex);

#ifdef XDEBUG

syslog(LOG_USER | LOG_DEBUG, "Start EXECL");

#endif

execl("./CGI/final.py", "CGI", numa, pwda, servera, (char *)NULL);

}

else if(cgi > 0)

{

waitpid(cgi, NULL, 0);//wait for child

//close(infd);

shutdown(infd, SHUT_RDWR);

pthread_mutex_lock(&mutex);

(*value)--;

res = *value;

pthread_mutex_unlock(&mutex);

free(num);

free(password);

free(server);

munmap(pmmap, sizeof(int32_t));

#ifdef XDEBUG

syslog(LOG_USER | LOG_DEBUG, "Child : %d END: %d",getpid(), res);

#endif

exit(0);

}

else

{

free(num);

free(password);

free(server);

munmap(pmmap, sizeof(int32_t));

exit(EXIT_FAILURE);

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值