C ++를 서버 측 웹 개발 언어로 사용할 수 있습니까? [닫은]


34

서버 측에서 "스크립트 언어"로 C ++를 사용하여 웹 개발을 시작하고 싶습니다. 내 서버 인프라는 * nix 기반이므로 Azure에서 C ++로 웹 개발을 수행 할 수 없으며 C ++ / CLI ASP.NET도 적용 할 수 없습니다.

레거시 CGI 응용 프로그램과 별도로 C ++를 사용하여 웹 개발을 수행 할 수 있습니까?


33
물론 문제는 가능하다 . 그것은 실제 ?
Ed S.

stackoverflow.com 에서이 질문 을 참조하십시오 .
케빈 클라인

24
기울어지면 서버 측 언어로 어셈블리를 사용할 수 있습니다.
Channel72

8
심지어 Brainf는 * CK 경우가 ,있습니다 .소켓로 리디렉션됩니다.
dan04

4
이것은 내가 참여한 첫 번째 웹 프로젝트에 대한 끔찍한 기억을 되살린다. CGI는 C 코드로가는 게이트웨이이다. 나는 그것에 대해 생각할 때 여전히 떨고있다! :-)
Brian Knoblauch

답변:


56

물론.

Wt , cppcms , CSP 등을 포함하여 개발을위한 몇 가지 프레임 워크가 있습니다. FastCGI의 기본 구현은 C로되어 있으며 C ++를 포함한 여러 언어를 직접 지원합니다 .

문자열을 구문 분석 할 수있는 모든 프로그래밍 언어는 CGI 또는 서블릿에서 사용할 수 있습니다. C 라이브러리와의 바인딩을 구현할 수있는 모든 언어를 사용하여 ISAPI 또는 Apache 호환 서버용 모듈을 개발할 수도 있습니다.

C ++에서는 특히 쉽지 않으며 훌륭한 템플릿 엔진은 거의 없으며 그 사이도 가능합니다.

물론 이것이 좋은 아이디어인지의 문제는 전적으로 또 다른 문제입니다. :)

참고 : Amazon.com, eBay 및 Google과 같은 주요 웹 사이트는 인프라의 일부로 C ++을 사용합니다. 그러나 Google은 속도가 중요한 시스템에 C ++ 만 사용하고 Amazon.com은 비교적 최근에 Lisp (일부 직원을 화나게 한)와 떨어져 전환했습니다.

Facebook은 이전에 PHP를 C ++로 컴파일했지만 HipHop 컴파일러 (부분적으로 C ++로 작성)는 바이트 코드 가상 머신으로 재구성되었습니다.


2
+1 다양한 프레임 워크 인용. amazon.com, google.com, 이제 hiphop을 통해 facebook.com 등 c ++ (및 기타 언어)로 (매우) 큰 웹 앱을 구동하는 것이 일반적이라는 사실을 추가해야합니다.
Klaim

7
@ 클라 임 : 일반적이지만 규칙은 아닙니다. Amazon의 아키텍처는 역사적으로 Lisp 기반이며 최근에는 C ++로만 다시 작성되었습니다. Google의 아키텍처에는 여러 가지 이유로 Java, Python 등이 C ++만큼 자주 사용됩니다. Facebook은 PHP가 확장되지 않는다는 것을 알았으므로 힙합 만 사용합니다. :)
greyfade

4
나는 동의하지만, 나는 그들이 여전히 원래 질문 제목에 직접 대답하기 위해 C ++ 사용의 잘 알려진 예임을 의미했습니다.
Klaim

1
@johannes Facebook의 확장 문제는 특히 최적화 된 PHP 스크립트의 성능 저하로 인해 필요한 것보다 훨씬 많은 서버를 유지해야한다는 사실에서 비롯됩니다. 이러한 대규모 인프라에는 선형 확장만으로는 충분하지 않습니다. 그러나 "공유 없음"접근 방식은 PHP에만 국한되지 않습니다. C와 C ++도 그렇게 할 수 있습니다.
greyfade

1
@amar 기본 성능이 필요한 앱의 0.1 %를 제외하고는 거의 수익이 없습니다. 훌륭한 웹 스택 지원을 통해 대부분의 다른 언어로 1/3의 시간을 봉사 할 수 있습니다. 은행, 웹 광고주 등은 모두 C ++에 의존하지 않고 대규모로 서비스를 제공합니다. 페이스 북도. 지저귀다. 스택 오버플로. 모두 더 높은 수준의 언어로 수행합니다. 여기에 머물러 있지만 다시 대다수가되지는 않습니다. 아마.
Rig

18

왜 안돼?

OkCupid 데이트 사이트는 C ++로 작성됩니다. 다른 예가있을 수 있습니다.

Wt 라는 C ++로 웹 애플리케이션을 개발하기위한 Qt에서 영감을 얻은 툴킷도 있습니다 .


11
"왜 안돼 ?" 이런 종류의 것을 더 많이 지원하는 언어를 사용하는 것이 훨씬 쉽습니다.
Ed S.

5
@Ed S. I와 greyfade가 지적했듯이 C ++로 웹 응용 프로그램을 개발하기위한 프레임 워크가 있습니다.
Vitor Py

2
예, 그러나 더 일반적으로 사용되는 프레임 워크만큼 쉽게 사용할 수 있습니까? 나는 솔직히 묻습니다. 저는 웹 개발자가 아니며 결코 사용하지는 않았지만 루비 / 파이썬 / PHP와 같이 성숙하지 않거나 널리 사용되지 않을 가능성이 있습니다.
Ed S.

3
@EdS .: 루비도 파이썬도 웹 프레임 워크로 시작하지 않았습니다. 실제로 등장하는 데 10 년이 걸렸습니다. 프레임 워크는 문제 Y에 언어 X를 사용하려는 충분한 사람들의 결과 일뿐입니다. C ++에서도 마찬가지입니다. 그렇지 않은 주된 이유 : C ++은 관리되지 않고 컴파일하는 데 오랜 시간이 걸리며 일반적으로 진입 장벽이 높습니다.
back2dos

1
@ back2dos : 어느 언어가 웹을 염두에두고 개발되었다고 누가 말했습니까? 나는 확실히하지 않았다. "지원"이라는 용어를 사용했습니다.
Ed S.

11

C ++로 웹 응용 프로그램을 작성하려는 경우 웹 응용 프로그램을 CGI로 인터페이스하는 것은 총 낭비입니다.

ASIO (Asynchronous I / O)를 사용하여 비동기식으로 빌드하는 것이 좋습니다. 이를 통해 굉장히 빠른 웹 서비스를 구축 할 수 있습니다 ( 최상의 효과를 위해 리버스 프록시 및 정적 서버 로 nginx와 결합 ). 이를 Wt 와 같은 템플릿 라이브러리와 결합 하면 단일 서버에서 초당 수만 건의 요청을 처리 할 수 ​​있습니다.

이것이 동적 언어 웹 프레임 워크에 대한 실용적인 대안인지 여부는 또 다른 문제입니다.


9

짧은 대답은 ANYTHING을 사용하여 웹 페이지를 작성하여 입력을 읽고 해석 가능한 출력을 작성할 수 있으며 웹 서버에서 실행할 수 있다는 것입니다.

기술적으로 모든 언어는 CGI 스크립트로 사용할 수 있습니다.

  1. 서버가 제시 한 모든 입력과 환경을 해석
  2. 알려진 마크 업 언어 (일반적으로 html)로 출력
  3. 서버에서 실행할 수 있습니다

다른 방법들도 있습니다. Perl은 c / c ++ 코드를 감싸는 래퍼 (wrapper)로 구축 될 수 있으며, 둘 사이의 해석 계층 역할을합니다 (C로 평평하게 컴파일 된 perl 모듈은 포함되지 않음).



5

마이크로 소프트도 가능하다고 생각하는 것 같습니다. C ++를 사용하여 Azure에 대한 새로운 도구 집합 인 Casablanca 를 확인하십시오 .

카사 블랑카 (Casablanca)는 클라우드 컴퓨팅이 대표하는 소프트웨어 아키텍처의 급격한 변화를 활용하려는 C ++ 개발자를 지원하는 방법을 모색하기위한 프로젝트입니다.

Casablanca를 통해 얻을 수있는 혜택은 다음과 같습니다.

  • HTTP, JSON 및 URI에 대한 비동기 C ++ 바인딩을 제공하여 Windows Vista, Windows 7 및 Windows 8 Consumer Preview의 기본 코드에서 REST 서비스 액세스 지원
  • Windows 8 Metro 스타일 앱에서 C ++ HTTP 클라이언트 측 코드를 작성하는 데 도움이되는 Visual Studio 확장 SDK
  • Visual Studio 통합을 포함하여 Azure 용 네이티브 코드 REST 작성 지원
  • 퍼스트 클래스 PaaS (Platform-as-a-Service) 기능으로 네이티브 클라이언트에서 Azure Blob 및 큐 스토리지에 액세스하기위한 편리한 라이브러리
  • C ++ 11 기능을 기반으로 비동기 작업을 구성하기위한 일관되고 강력한 모델
  • Erlang 액터 기반 프로그래밍 모델의 C ++ 구현
  • 샘플 및 문서 세트

2

PHP 의 경우 고유 한 C / C ++ 확장을 작성하여 좋은 성능 이점을 얻을 수 있습니다. 내 웹 응용 프로그램에서 CPU를 많이 사용하는 부분이 있다면 그 처리를 확장으로 오프로드 한 다음 C로 결과를 PHP로 반환 한 다음 PHP에서 브라우저로 출력하는 작은 C ++ 라이브러리를 만들 것입니다.

사람들이 종종 고려하지 않는 다른 것은 JavaScript / jQuery와 같은 특정 CPU 처리를 클라이언트 측으로 오프로드하는 것입니다. 웹 서버가 있다면 특정 기능 (일부 데이터 처리)에 대해 CPU 집약적 처리를 수행하려면 3Ghz CPU가 필요할 수 있습니다. 우리 회사는 서버를 계속 운영하기 위해 매달 해당 서버에 대한 비용을 지불하고 있습니다. CPU 집약적 작업을 동시에 실행하는 100 명의 동시 사용자에 대한 작업을 동시에 확장하려면 여러 개의 CPU와 서버가 필요할 수 있으므로 비즈니스 비용이 증가합니다. CPU 집약적 작업을 클라이언트 측에 오프로드하면 웹 사이트를 방문하는 각 사용자가 데이터를 직접 처리 할 수 ​​있으며 서버 기능을 늘릴 필요가 없으므로 비용이 절약됩니다.

결국 100 개 이상의 데스크톱 / 태블릿 / 모바일의 강력한 처리 능력을 통해 처리를 수행하면 매월 비즈니스 비용이 발생하는 데이터 센터에 서버가 앉아있는 것보다 훨씬 많은 성능을 발휘합니다. 잠재적으로 모든 서버가 데이터베이스에서 데이터를 검색하여 데이터베이스에 다시 저장하기 전에 콘텐츠와 데이터의 사전 / 사후 처리 및 유효성 검사를 제공합니다. 분명히 클라이언트 측 코드를 너무 CPU 집약적으로 사용하여 웹 브라우저 UI를 차단 / 고정시킬 수는 없습니다. 서버에 대한 AJAX 요청을 발생시키고 데이터를 검색 한 다음 비동기 적으로 클라이언트 측에서 데이터를 처리하여 웹을 남겨 둘 수 있습니다 -브라우저 UI를 완전히 사용할 수 있습니다.


2

예, 사용할 수 있습니다. 다른 사람들은 다양한 접근법을 언급했습니다. 여기 내 자신의 접근 방식이 있습니다. 장점은 완전히 이식 가능하고 독립적이며 선택 된 모든 라이브러리는 ANSI C에만 의존한다는 것입니다. Linux 커널 및 C 컴파일러 (및 Busybox, bash 등의 명백한 것들) (또는 Windows 만 필요) 그리고 컴파일러), 추가 라이브러리가 필요 없으며 멋진 설치가 필요하지 않습니다.

결과는 웹 서버와 동적 페이지 생성기 ( "apache"및 "php"를 모두 대체) 인 단일 프로그램이며 sqlite를 통해 데이터베이스에 액세스 할 수 있습니다.

사용 된 라이브러리 :

  • 몽구스-HTTP 서버
  • Sqlite-SQL 데이터베이스
  • MiniXML-동적 페이지 생성이 쉬워집니다. 자바 스크립트와 같은 종류createElement

이 답변의 나머지 부분은 Linux를위한 완전한 설정 안내서입니다. SQlite와 MiniXML은 모두 선택 사항이지만이 가이드는 전체 설치를 다룹니다. sqlite 또는 MiniXML을 비활성화하려는 경우 필요하지 않은 부분을 주석 처리하는 것은 사용자의 몫입니다.

1. 3 개의 라이브러리를 다운로드하십시오

2. 폴더 준비

  • 빈 폴더를 만듭니다 (기본 폴더라고 함).
  • 다음 파일을 넣으십시오.
    • sqlite tar.gz에서 : sqlite3.c , sqlite3.h
    • 몽구스 지퍼에서 : mongoose.c , mongoose.h
    • mxml tar.gz에서 : mxml.h

3. mxml 컴파일

mxml.c가 누락되었음을 알 수 있습니다. 정적 mxml 라이브러리를 만들어야하기 때문입니다. mxml tar.gz가 다운로드 된 폴더로 이동하여 다음을 수행하십시오.

tar -xvf mxml-<version>.tar.gz #Extract the tar
cd mxml-<version> #Go to the newly extracted directory
./configure #prepare the compiler
make #compile, you may need to install "make" first.

컴파일이 끝나면 많은 파일이 생성됩니다. 관심있는 유일한 파일은 libmxml.a해당 파일을 기본 폴더에 복사하는 것입니다 .

3.1 재확인

기본 폴더에 다음이 있는지 확인하십시오.

  • 몽구스의 경우 : mongoose.c, mongoose.h
  • mxml의 경우 : libmxml.a, mxml.h
  • sqlite의 경우 : sqlite.c, sqlite.h

4. main.c

실제 프로그램을 작성 main.c하고 기본 폴더에 파일을 작성합시다 . 여기에 시작하는 데 필요한 골격이 있습니다.

#include <string.h>
#include <stdio.h>

#include "mongoose.h"
#include "mxml.h"
#include "sqlite3.h"

/***Sqlite initialization stuff***/
//comment out everything sqlite related if you don't want sqlite, including the callback function and the include "sqlite3.h"
static int callback(void * custom, int argc, char **argv, char **azColName);
char *zErrMsg = 0;
sqlite3 *db;
int rc;

/***Just some laziness shortcut functions I made***/
typedef mxml_node_t * dom; //type "dom" instead of "mxml_node_t *"
#define c mxmlNewElement   //type "c" instead of "mxmlNewElement"
inline void t(dom parent,const char *string) //etc
{
    mxmlNewText(parent, 0, string);
}

//type "sa" instead of "mxmlElementSetAttr"
inline void sa(dom element,const char * attribute,const char * value) 
{
    mxmlElementSetAttr(element,attribute,value);
}




//The only non boilerplate code around in this program is this function
void serve_hello_page(struct mg_connection *conn)
{
    char output[1000];
    mg_send_header(conn,"Content-Type","text/html; charset=utf-8");
    mg_printf_data(conn, "%s", "<!DOCTYPE html>");
    //This literally prints into the html document


    /*Let's generate some html, we could have avoided the
     * xml parser and just spat out pure html with mg_printf_data
     * e.g. mg_printF_data(conn,"%s", "<html>hello</html>") */

    //...But xml is cleaner, here we go:
            dom html=mxmlNewElement(MXML_NO_PARENT,"html");
                dom head=c(html,"head");
                    dom meta=c(head,"meta");
                    sa(meta,"charset","utf-8");
                dom body=c(html,"body");
                    t(body,"Hello, world<<"); //The < is auto escaped, neat!
                    c(body,"br");
                    t(body,"Fred ate bred");    
                dom table=c(body,"table");
                sa(table,"border","1");

                //populate the table via sqlite
                rc = sqlite3_exec(db, "SELECT * from myCoolTable", callback, table, &zErrMsg);
                if( rc!=SQLITE_OK )
                {
                    fprintf(stderr, "SQL error: %s\n", zErrMsg);
                    sqlite3_free(zErrMsg);
                }

            mxmlSaveString (html,output,1000,  MXML_NO_CALLBACK);
            mg_printf_data(conn, "%s", output);
            mxmlDelete(html); 
}

//sqlite callback
static int callback(void * custom, int argc, char **argv, char **azColName)
{
    //this function is executed for each row
    dom table=(dom)custom;

    dom tr=c(table,"tr");
    dom td;
    int i;
    for(i=0; i<argc; i++)
    {
        td=c(tr,"td");
        if (argv[i])
            t(td, argv[i]);
        else
            t(td, "NULL");

        printf("%s == %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
    }
     printf("\n");
     return 0;
}


static int event_handler(struct mg_connection *conn, enum mg_event ev)
{
    if (ev == MG_AUTH)
    {
        return MG_TRUE;   // Authorize all requests
    }
    else if (ev == MG_REQUEST)
    {
        if (!strcmp(conn->uri, "/hello"))
        {
            serve_hello_page(conn);
            return MG_TRUE;   // Mark as processed
        }
    }
    return MG_FALSE;  // Rest of the events are not processed

}

int main(void)
{
    struct mg_server *server = mg_create_server(NULL, event_handler);
    //mg_set_option(server, "document_root", "."); //prevent dir listing and auto file serving
    //TODO can I allow file listing without dir listing in a specified directory?
    mg_set_option(server, "listening_port", "8080");


    rc = sqlite3_open("db.sqlite3", &db); 

    if( rc )
    {
        fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
        sqlite3_close(db);
        return(1);
    }

    printf("Server is running on port 8080!\n");
    for (;;)
    {
        mg_poll_server(server, 1000);  // Infinite loop, Ctrl-C to stop
    }
    mg_destroy_server(&server);
    sqlite3_close(db);

    return 0;
}




/*
 * useful stuff:
 * mg_send_file(struct mg_connection *, const char *path); - serve the file at *path*/

마지막으로 컴파일!

컴파일합시다. cd기본 폴더에 넣고 다음을 실행하십시오.

gcc -c main.c
gcc -c mongoose.c
gcc -c sqlite3.c
gcc -o server.out main.o mongoose.o sqlite3.o -ldl -lpthread -lmxml -L . 

이제로 server.out을 실행 /server.out하고localhost:8080/hello

완료 :)



@Hey :이 몽구스 대안을 지적 해 주셔서 감사합니다. 저는 항상 커뮤니티 중심 프로젝트를 선호합니다. 나는 철저히 테스트 한 후에 아마도 Mongoose를 Civetweb으로 대체 할 것입니다.
Hello World

0

여러 임베디드 시스템 (예 : 라우터, 프린터 등)에 C ++ 기반 웹 서버가 있다고 생각합니다.

특히 libonion 과 같은 일부 HTTP 서버 라이브러리를 사용 하여 일부 C 또는 C ++ 프로그램에 웹 기능을 추가하거나 일부 웹 인터페이스가있는 라이트 서버를 개발할 수 있습니다.

일부 사람들은 Ocsigen을 사용하여 Ocaml에서 웹 서버 또는 HTTP 인터페이스를 코딩하고 있습니다. 모든 웹이 PHP 인 것은 아닙니다. 또한 FastCGI를 사용 하면 응용 프로그램에서 / 웹으로 동적 웹 처리를 할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.