어떻게 C 로 웹 서버 의 기본 기능 을 씁 니까?
목표 구조
nginx 의 사상 으로 본 서버 구 조 를 고려 하고 다음 과 같은 그림 을 초보 적 으로 고려 합 니 다.
물론 php 프로 세 스 도 다른 스 크 립 트 언어 로 바 꿀 수 있 으 며,원본 코드 의 command 변 수 를 변경 할 수 있 습 니 다.
서버 에 master 프로 세 스 가 있 습 니 다.여러 개의 키 프로 세 스 가 worker 프로 세 스 입 니 다.master 프로 세 스 는 클 라 이언 트 의 요청 을 받 은 다음 worker 프로 세 스 에 나 누 어 줍 니 다.worker 프로 세 스 는 http 헤더 정 보 를 처리 한 후 phop 프로 세 스 에 파 라 메 터 를 전달 한 후 결 과 를 상부 로 되 돌려 클 라 이언 트 에 응답 합 니 다.
phop-fpm 의 worker 프로 세 스 풀 방식 도 고려 한 적 이 있 습 니 다.그러면 phop-fpm 프로 세 스 도 모방 해 야 합 니 다.아직 내부 구조 에 익숙 하지 않 습 니 다.단순화 할 수 있다 면 자 연 스 럽 게 접근 할 수 있 습 니 다.현재 PHP 의 SAPI 인터페이스 에 익숙 하지 않 으 니 알 아 보고 생각해 보 세 요.
현재 상태
현재 상태의 서버 는 매우 간단 합 니 다.정리 해 보면 다음 과 같은 부분 이 최적화 되 어야 합 니 다.
이 는 로 컬 주소 의 8080 포트 를 감청 하고 받 은 http 헤드 의 path 정 보 를 phop 프로 세 스에 제출 합 니 다.phop 프로 세 스 는 매개 변수 정 보 를 처리 한 후 서버 에 되 돌려 주 고 서버 는 http 응답 정 보 를 조합 하여 결 과 를 클 라 이언 트 에 게 되 돌려 줍 니 다.
다음은 각 기능 의 실현 을 소개 한다.
기능 실현
socket 시리즈 방법
소개 함수 사이 에 http 요청 에서 클 라 이언 트 와 서버 간 의 상호작용 을 그림 으로 소개 합 니 다.
그림:서버 생 성 진행:
1.socket()을 호출 하여 연결 만 들 기;int socket(int domain, int type, int protocol);
2.bind()를 호출 하여 소켓 이름,바 인 딩 포트;int bind( int socket, const struct sockaddr *address, size_t address_len);
3.listen()을 호출 하여 이 소켓 을 감청 합 니 다.int listen(int socket, int backlog);
4.accept()를 호출 하여 클 라 이언 트 의 연결 을 받 습 니 다.int accept(int socket, struct sockaddr *address, size_t *address_len);
5.recv()를 호출 하여 클 라 이언 트 의 정 보 를 받 습 니 다.int recv(int s, void *buf, int len, unsigned int flags);
6.send()를 호출 하여 응답 정 보 를 클 라 이언 트 에 게 보 냅 니 다.int send(int s, const void * msg, int len, unsigned int falgs);
socket 간 의 수신 과 전송 정 보 는 C 에서 몇 가지 시리즈 가 있 습 니 다.write()/read(),send()/recv(),sendto()/recvfrom(),sendmsg()/recvmsg()는 스스로 선택 할 수 있 습 니 다.
또한 함수 매개 변수 해석 과 요점 은 모두 제 가 코드 에 주석 을 달 았 습 니 다.관심 이 있 는 것 은 끌 어 내 려 서 볼 수 있 습 니 다.이런 것들 은 인터넷 에서 도 많이 소개 되 었 습 니 다.여 기 는 더 이상 군말 하지 않 겠 습 니 다.
서버 와 PHP cli 의 상호작용
그 다음 에 C 프로 세 스 와 php 프로 세 스 의 상호작용 입 니 다.간단 하고 사용 하기 쉬 운 점 을 고려 하여 현재 C 프로 세 스에 서 php 스 크 립 트 를 직접 실행 합 니 다.
처음에 system()함수 사용:int system(const char*command);
시스템 함 수 는 하위 프로 세 스 에서 php 스 크 립 트 를 cli 방식 으로 실행 하고 오류 코드 나 값 을 되 돌려 줍 니 다.결과 형식 을 제어 할 수 없 기 때문에 컴 파일 할 때 warning 을 알려 줍 니 다.또한 부모 프로 세 스에 결 과 를 되 돌려 줄 때 표준 출력 에서 결 과 를 출력 하고 서버 가 실 행 될 때 이상 을 던 집 니 다.
그래서 다른 방법 popen,FILE*popen(const char*command,const char*type)을 찾 았 습 니 다.:
popen 역시 fork 키 프로 세 스 를 실행 한 다음 하위 프로 세 스 에 연 결 된 표준 출력 장치 나 표준 입력 장 치 를 만 들 고 파일 지침 을 되 돌려 줍 니 다.다음 프로 세 스 는 이 파일 포인터 로 하위 프로 세 스 의 출력 장 치 를 읽 거나 하위 프로 세 스 의 표준 입력 장치 에 기록 할 수 있 습 니 다.
type 매개 변 수 는 하위 프로 세 스 에 연 결 된 표준 입력 을 제어 하 는 것 입 니까?표준 출력 을 제어 하 는 것 입 니까?하위 프로 세 스 의 표준 출력 을 원 하기 때문에 type 인 자 를 문자'r'(read)로 입력 합 니 다.마찬가지 로 하위 프로 세 스 표준 입력 을 쓰 려 면'w'(write)값 을 전달 할 수 있 습 니 다.
또한 버퍼 내용 을 받 을 때 도 약간의 의외 의 사고 가 발생 했 습 니 다.사용 하 는 fgets()방법 은 줄 바 꿈 문자
로 끝 납 니 다.phop 프로 세 스 출력 을 받 을 때 줄 바 꿈 이 끝 납 니 다.중간 문자열 배열line
을 사용 하여 줄 마다 정 보 를 받 고 줄 마다 정 보 를 조합 합 니 다.코드 는 다음 과 같 습 니 다:
char * execPHP(char *args){
// , command , args ,
char command[BUFF_SIZE] = "php /Users/mfhj-dz-001-441/CLionProjects/cproject/tinyServer/index.php ";
FILE *fp;
static char buff[BUFF_SIZE]; //
char line[BUFF_SIZE];
strcat(command, args);
memset(buff, 0, BUFF_SIZE); // ,
if((fp = popen(command, "r")) == NULL){
strcpy(buff, " ");
}else{
// fgets ,
while (fgets(line, BUFF_SIZE, fp) != NULL){
strcat(buff, line);
};
}
return buff;
}
메시지 데이터 처리socket 은 응용 층 과 전송 층 사이 의 가상 층 에 있 습 니 다.서버 socket 프로 토 콜 형식 을 TCP 로 설정 하기 때문에 TCP 의 악수,손 흔 들 기,데이터 읽 기 등 절 차 는 우리 에 게 투명 합 니 다.우리 가 얻 은 데 이 터 는 HTTP 메시지 입 니 다.HTTP 메시지 구조 와 필드 해석 에 관 한 글 이 매우 많 습 니 다.여기 서도 더 이상 언급 하지 않 습 니 다.
먼저 C 의 strtok()방법 을 사용 하여 HTTP 헤드 의 첫 줄 을 얻 고 http 방법 과 path 정 보 를 얻 으 며 이 정 보 를 처리 한 후 sprintf()방법 으로 HTTP 응답 메 시 지 를 결합 하여 응답 내용 의 길이 와 응답 내용 을 대체 합 니 다.
이상 은 C 로 웹 서버 의 기본 기능 을 어떻게 쓰 는 지 에 대한 상세 한 내용 입 니 다.C 로 웹 서버 의 기본 기능 을 쓰 는 것 에 관 한 자 료 는 저희 의 다른 관련 글 을 주목 하 시기 바 랍 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Docker를 사용한 React 및 .NET Core 6.0 샘플 프로젝트 - 1부이 기사에서는 Entity Framework Core Code First 접근 방식을 사용하는 ASP.NET Core 6.0 WEP API의 CRUD(만들기, 읽기, 업데이트 및 삭제) 작업에 대해 설명합니다. 웹 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.