손 으로 nginx 로 자신의 서버 를 개발 하 는 것 을 가 르 칩 니 다 --- nginx 를 이용 하여 hello World 프로그램 을 개발 합 니 다 (1)
코드 를 급히 훑 어보 지 말고 왜 이 칼럼 을 쓰 고 싶 은 지 먼저 이야기 하 세 요. 사실 본인 도 서버 개발 초보 입 니 다. 나이 가 조금 들 면 반응 과 기억력 이 많이 떨 어 지 는 것 같 습 니 다. 뭔 가 를 써 서 기억 할 수 있 도록 도와 야 합 니 다.이 칼럼 은 많은 nginx 초보 자 들 이 nginx 를 조금 더 깊이 이해 하 는 데 도움 이 될 것 입 니 다. 제 모든 글 은 길지 않 지만 중요 한 점 이 있 습 니 다. 만약 에 저 를 따라 계속 공부 하면 nginx 로 자신의 웹 서버 를 구축 하 는 방법 을 배 울 것 입 니 다. nginx 로 자신의 역방향 프 록 시 서버 를 구축 하 는 것 을 배 울 것 입 니 다. 그리고 만약 에 당신 이 충분히 진지 하 다 면...nginx 의 각종 고급 특성, 예 를 들 어 메모리 정렬 이 가 져 온 고 효율, slab 알고리즘, 각종 풀 (메모리 풀, 연결 풀) 에 대해 서도 어느 정도 알 수 있 습 니 다.nginx 를 설명 하 는 동시에 저 는 nginx 중의 많은 네트워크 특성 과 결합 하여 기 존의 최첨단 지식 을 설명 할 것 입 니 다.예 를 들 어 http 2.0, tles 1.3 등 제 글 에 오류 가 있 는 것 을 발견 하면 여러분 의 지적 을 환영 합 니 다.
본 격 적 으로 nginx 를 시작 하기 전에 다음 echo 서버 가 어떻게 했 는 지 기억 합 니 다.
#include
#include
#include
#include
#include
#define EHCO_PORT 8080
#define MAX_CLIENT_NUM 10
int main()
{
int socketfd;
socketfd = socket(AF_INET, SOCK_STREAM, 0);
if(socketfd == -1)
{
printf("errno=%d ", errno);
exit(1);
}
else
{
printf("socket create successfully ");
}
struct sockaddr_in sa;
bzero(&sa, sizeof(sa));
sa.sin_family = AF_INET;
sa.sin_port = htons(EHCO_PORT);
sa.sin_addr.s_addr = htons(INADDR_ANY);
bzero(&(sa.sin_zero), 8);
if(bind(socketfd, (struct sockaddr *)&sa, sizeof(sa))!= 0)
{
printf("bind failed ");
printf("errno=%d ", errno);
exit(1);
}
else
{
printf("bind successfully ");
}
//listen
if(listen(socketfd ,MAX_CLIENT_NUM) != 0)
{
printf("listen error ");
exit(1);
}
else
{
printf("listen successfully ");
}
int clientfd;
struct sockaddr_in clientAdd;
char buff[101];
socklen_t len = sizeof(clientAdd);
int closing =0;
while( closing == 0 && (clientfd = accept(socketfd, (struct sockaddr *)&clientAdd, &len)) >0 )
{
int n;
while((n = recv(clientfd,buff, 100,0 )) > 0)
{
printf("number of receive bytes = %d ", n);
write(STDOUT_FILENO, buff, n);
send(clientfd, buff, n, 0);
buff[n] = '';
if(strcmp(buff, "quit ") == 0)
{
break;
}
else if(strcmp(buff, "close ") == 0)
{
//server closing
closing = 1;
printf("server is closing ");
break;
}
}
close(clientfd);
}
close(socketfd);
return 0;
}
모든 서버 는 그 몇 가지 기본 적 인 함수, socket (), bind (), listen (), connect (), accept (), read (), write (), send (), recv () 를 피 할 수 없다. 아무리 고급 서버 라 도 본질 적 으로 운영 체제 가 준 IO 재 활용 과 각종 디자인 모델 을 이용 하여 이 몇 개의 인 터 페 이 스 를 봉인 했다.서버 개발 을 공부 할 때 개인 적 으로 이 본질 을 파악 해 야 한다 고 생각 합 니 다.
echo 서버 가 어떻게 만 들 었 는 지 기억 한 후에 말 할 수 밖 에 없 는 기본 지식 인 이벤트 구동 체 제 를 복습 합 니 다.무엇이 사건 구동 메커니즘 입 니까?말 그대로 하나의 사건 이 와 야 다음 사건 을 촉발 하고 하나의 사건 이 하나의 사건 을 촉발 시 켜 층 층 이 추진 하 는 것 이다.문 자 는 말하자면 매우 추상 적 이다. 사실은 본질 적 으로 select, poll, epoll 등 몇 개의 IO 다 중 복합 함수 가 리 셋 함수 와 결합 하여 이 루어 진 구조 이다.다음 간단 한 epoll 서버 의 논 리 를 살 펴 보 겠 습 니 다.
// epoll , epoll github https://github.com/zk3326312/EpollServer
if((listenfd = socket(AF_INET,SOCK_STREAM,0)) == -1)
{
perror("socket error");
return -1;
}
memset(&serveraddr,0,sizeof(serveraddr));
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
serveraddr.sin_port = htons(default_port);
serveraddr.sin_family = AF_INET;
if( bind(listenfd,(sockaddr*)&serveraddr,sizeof(sockaddr)) == -1)
{
cout<add(listenfd,EPOLLIN);
while(true)
{
int nfds = sp_Epoll->wait(maxfdNUM,-1);
for(int i = 0;i < nfds;i++)
{
if(sp_Epoll->_events[i].data.fd == listenfd)
{
if((confd = accept(listenfd,(sockaddr*)&clientaddr,&clilen)) == -1)
{
cout<add(confd,EPOLLIN);
}
else if((sp_Epoll->_events[i].events & EPOLLIN) == EPOLLIN)
{
int tempfd = sp_Epoll->_events[i].data.fd;
if(tempfd < 0)
{
continue;
}
char buffer[buffer_len];
int n = 0;
if((n = recv(tempfd,buffer,buffer_len,0)) > 0)
{
cout<< "receive message is"<< buffer<_events[i].data.fd = -1;
continue;
}
else if(errno == EINTR)
{
cout << "connect problem"<_events[i].data.fd = -1;
cout << "the connection is terminated by client"<mod(confd,EPOLLOUT);
}
else if((sp_Epoll->_events[i].events & EPOLLOUT) == EPOLLOUT)
{
int tempfd = sp_Epoll->_events[i].data.fd;
send(tempfd,"success recv your message",25,0);
//sp_Epoll->del(tempfd);
sp_Epoll->mod(tempfd,EPOLLIN);
}
}
}
return 0;
}
처음 엔 nginx 의 코드 를 보 았 을 때 많 고 복잡 하 며 곳곳에 리 셋 과 매크로 가 있어 서 사람 으로 하여 금 손 을 쓸 수 없 게 만 들 었 습 니 다. (모 르 겠 습 니 다. 정말 당신 을 탓 하지 않 습 니 다) 하지만 사건 구동 이라는 본질 을 잘 기억 할 때 당신 은 많이 뚜렷 해 집 니 다. 전체 과정 은 연결 되 었 을 뿐만 아니 라 등록 읽 기와 쓰기 사건 이 epoll 에 들 어간 다음 에 fd 가 준비 되면 처리 하 세 요. 잘 소화 하 세 요.다음 글 은 nginx 의 hello World 기능 을 본 격 적 으로 작성 해 야 합 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.