resp协议定义, xml定义配置文件
This commit is contained in:
745
NtyCo/sample/nty_http_epoll.c
Normal file
745
NtyCo/sample/nty_http_epoll.c
Normal file
@@ -0,0 +1,745 @@
|
||||
/*
|
||||
* Author : WangBoJing , email : 1989wangbojing@gmail.com
|
||||
*
|
||||
* Copyright Statement:
|
||||
* --------------------
|
||||
* This software is protected by Copyright and the information contained
|
||||
* herein is confidential. The software may not be copied and the information
|
||||
* contained herein may not be used or disclosed except with the written
|
||||
* permission of Author. (C) 2017
|
||||
*
|
||||
*
|
||||
|
||||
**** ***** *****
|
||||
*** * ** ***
|
||||
*** * * * **
|
||||
* ** * * ** **
|
||||
* ** * * ** *
|
||||
* ** * ** ** *
|
||||
* ** * *** **
|
||||
* ** * *********** ***** ***** ** ****
|
||||
* ** * ** ** ** ** ** **
|
||||
* ** * ** ** * ** * **
|
||||
* ** * ** * * ** ** **
|
||||
* ** * ** ** * ** * **
|
||||
* ** * ** * * ** ** **
|
||||
* ** * ** ** * ** ** **
|
||||
* ** * ** ** * ** ** **
|
||||
* ** * ** * * ** ** **
|
||||
* ** * ** ** * ** * ** **
|
||||
* *** ** * * ** * ** **
|
||||
* *** ** * ** * * ** **
|
||||
* ** ** * ** ** * ** **
|
||||
* ** ** * * ** * ** **
|
||||
***** * **** * ***** ****
|
||||
*
|
||||
*
|
||||
*****
|
||||
****
|
||||
|
||||
|
||||
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysinfo.h>
|
||||
#include <sys/syscall.h>
|
||||
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <sys/sem.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <sys/epoll.h>
|
||||
#include <sys/poll.h>
|
||||
|
||||
#define __USE_GNU
|
||||
|
||||
#include <sched.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#define MAX_CLIENT_NUM 1000000
|
||||
#define TOTALFDS 16
|
||||
|
||||
typedef struct _shm_area {
|
||||
int totalfds[TOTALFDS];
|
||||
char cpu_lb[TOTALFDS];
|
||||
//mtx : default 0
|
||||
// 1 : lock -- del epoll
|
||||
// 2 : lock -- del complete
|
||||
// 3 : unlock -- add
|
||||
// 0 : unlock -- add complete
|
||||
int accept_mtx;
|
||||
} shm_area;
|
||||
|
||||
static shm_area *global_shmaddr = NULL;
|
||||
static int global_shmid = -1;
|
||||
|
||||
int cpu_size = 0;
|
||||
int accept_disable = 1000;
|
||||
int enable_accept = 1;
|
||||
pid_t self_id = 0;
|
||||
|
||||
|
||||
|
||||
unsigned long cmpxchg(void *addr, unsigned long _old, unsigned long _new, int size) {
|
||||
unsigned long prev;
|
||||
volatile unsigned int *_ptr = (volatile unsigned int *)(addr);
|
||||
|
||||
switch (size) {
|
||||
case 1: {
|
||||
__asm__ volatile (
|
||||
"lock; cmpxchgb %b1, %2"
|
||||
: "=a" (prev)
|
||||
: "r" (_new), "m" (*_ptr), "0" (_old)
|
||||
: "memory");
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
__asm__ volatile (
|
||||
"lock; cmpxchgw %w1, %2"
|
||||
: "=a" (prev)
|
||||
: "r" (_new), "m" (*_ptr), "0" (_old)
|
||||
: "memory");
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
__asm__ volatile (
|
||||
"lock; cmpxchg %1, %2"
|
||||
: "=a" (prev)
|
||||
: "r" (_new), "m" (*_ptr), "0" (_old)
|
||||
: "memory");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return prev;
|
||||
}
|
||||
|
||||
int atomic_add(volatile int *value, int add)
|
||||
{
|
||||
__asm__ volatile (
|
||||
|
||||
"lock;"
|
||||
" addl %0, %1; "
|
||||
|
||||
: "+r" (add) : "m" (*value) : "cc", "memory");
|
||||
|
||||
return add;
|
||||
}
|
||||
|
||||
int atomic_sub(volatile int *value, int sub)
|
||||
{
|
||||
__asm__ volatile (
|
||||
|
||||
"lock;"
|
||||
" subl %0, %1; "
|
||||
|
||||
: "+r" (sub) : "m" (*value) : "cc", "memory");
|
||||
|
||||
return sub;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define ISspace(x) isspace((int)(x))
|
||||
|
||||
#define SERVER_STRING "Server: ntyco_httpd/0.1.0\r\n"
|
||||
#define STDIN 0
|
||||
#define STDOUT 1
|
||||
#define STDERR 2
|
||||
|
||||
#define ENABLE_NTYCO 0
|
||||
|
||||
#if ENABLE_NTYCO
|
||||
|
||||
#define socket nty_socket
|
||||
#define accept nty_accept
|
||||
#define recv(a, b, c, d) nty_recv(a, b, c, d)
|
||||
#define send(a, b, c, d) nty_send(a, b, c, d)
|
||||
|
||||
#define MAX_BUFFER_LENGTH 1024
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#define INC_COUNTFD do { \
|
||||
atomic_add(&global_shmaddr->totalfds[self_id % cpu_size], 1); \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define DEC_COUNTFD do { \
|
||||
atomic_sub(&global_shmaddr->totalfds[self_id % cpu_size], 1); \
|
||||
} while (0)
|
||||
|
||||
int get_countfd(void) {
|
||||
return global_shmaddr->totalfds[self_id % cpu_size];
|
||||
}
|
||||
|
||||
int max_countfd(void) {
|
||||
|
||||
int count = -1;
|
||||
int i = 0;
|
||||
|
||||
for (i = 0;i < cpu_size;i ++) {
|
||||
if (count < global_shmaddr->totalfds[i]) {
|
||||
count = global_shmaddr->totalfds[i];
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
int min_countfd(void) {
|
||||
|
||||
int count = 0xffffffff;
|
||||
int i = 0;
|
||||
|
||||
for (i = 0;i < cpu_size;i ++) {
|
||||
if (count > global_shmaddr->totalfds[i]) {
|
||||
count = global_shmaddr->totalfds[i];
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
int compare_out_countfd(void) {
|
||||
|
||||
int current = get_countfd();
|
||||
int min = min_countfd();
|
||||
|
||||
if ((current * 7 / 8) > min) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int compare_in_countfd(void) {
|
||||
|
||||
int current = get_countfd();
|
||||
int max = max_countfd();
|
||||
|
||||
if ((current * 8 / 7) < max) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void print_countfds(void) {
|
||||
|
||||
int i = 0;
|
||||
for (i = 0;i < cpu_size;i ++) {
|
||||
printf("%5d : %5d ", i, global_shmaddr->totalfds[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void lock_accept(void) {
|
||||
|
||||
global_shmaddr->cpu_lb[self_id % cpu_size] = 1;
|
||||
|
||||
int count = 0xffffffff;
|
||||
int i = 0;
|
||||
|
||||
for (i = 0;i < cpu_size;i ++) {
|
||||
if (count > global_shmaddr->totalfds[i]) {
|
||||
count = global_shmaddr->totalfds[i];
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0;i < cpu_size;i ++) {
|
||||
if (count == global_shmaddr->totalfds[i]) {
|
||||
global_shmaddr->cpu_lb[i] = 3;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
char read_accept(void) {
|
||||
return global_shmaddr->cpu_lb[self_id % cpu_size];
|
||||
}
|
||||
|
||||
void write_accept(char state) { //0, 1, 2, 3
|
||||
global_shmaddr->cpu_lb[self_id % cpu_size] = state;
|
||||
}
|
||||
|
||||
int lock(void) {
|
||||
|
||||
return cmpxchg(&global_shmaddr->accept_mtx, 0, 1, 4); //zero:success, non-zero:failed
|
||||
|
||||
}
|
||||
|
||||
void unlock(void) {
|
||||
|
||||
global_shmaddr->accept_mtx = 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void accept_request(int fd, int epfd);
|
||||
void bad_request(int);
|
||||
void cat(int);
|
||||
void cannot_execute(int);
|
||||
void error_die(const char *);
|
||||
void execute_cgi(int, const char *, const char *, const char *);
|
||||
int get_line(int, char *, int);
|
||||
void headers(int);
|
||||
void not_found(int);
|
||||
void serve_file(int);
|
||||
int startup(u_short *);
|
||||
void unimplemented(int);
|
||||
|
||||
|
||||
ssize_t nsend(int fd, const void *buf, size_t len, int flags) {
|
||||
|
||||
int sent = 0;
|
||||
|
||||
int ret = send(fd, ((char*)buf)+sent, len-sent, flags);
|
||||
if (ret == 0) return ret;
|
||||
if (ret > 0) sent += ret;
|
||||
|
||||
while (sent < len) {
|
||||
#if 0
|
||||
struct pollfd fds;
|
||||
fds.fd = fd;
|
||||
fds.events = POLLIN | POLLERR | POLLHUP;
|
||||
poll(&fds, 1, -1);
|
||||
#endif
|
||||
ret = send(fd, ((char*)buf)+sent, len-sent, flags);
|
||||
//printf("send --> len : %d\n", ret);
|
||||
if (ret <= 0) {
|
||||
if (errno == EAGAIN) continue;
|
||||
|
||||
break;
|
||||
}
|
||||
sent += ret;
|
||||
}
|
||||
|
||||
if (ret <= 0 && sent == 0) return ret;
|
||||
|
||||
return sent;
|
||||
}
|
||||
|
||||
static int ntySetNonblock(int fd) {
|
||||
int flags;
|
||||
|
||||
flags = fcntl(fd, F_GETFL, 0);
|
||||
if (flags < 0) return flags;
|
||||
flags |= O_NONBLOCK;
|
||||
if (fcntl(fd, F_SETFL, flags) < 0) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ntySetReUseAddr(int fd) {
|
||||
int reuse = 1;
|
||||
return setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse));
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************/
|
||||
/* A request has caused a call to accept() on the server port to
|
||||
* return. Process the request appropriately.
|
||||
* Parameters: the socket connected to the client */
|
||||
/**********************************************************************/
|
||||
void accept_request(int fd, int epfd)
|
||||
{
|
||||
int client = fd;
|
||||
|
||||
char buf[1024];
|
||||
size_t numchars;
|
||||
char method[16];
|
||||
char url[32];
|
||||
char path[64];
|
||||
size_t i, j;
|
||||
struct stat st;
|
||||
int cgi = 0; /* becomes true if server decides this is a CGI
|
||||
* program */
|
||||
char *query_string = NULL;
|
||||
|
||||
numchars = recv(client, buf, sizeof(buf), 0);
|
||||
if (numchars == -1) {
|
||||
//printf("recv errno : %d\n", errno);
|
||||
if (errno == ECONNRESET) {
|
||||
close(client);
|
||||
|
||||
struct epoll_event ev;
|
||||
ev.events = EPOLLIN | EPOLLET;
|
||||
ev.data.fd = client;
|
||||
epoll_ctl(epfd, EPOLL_CTL_DEL, client, &ev);
|
||||
|
||||
DEC_COUNTFD;
|
||||
}
|
||||
} else if (numchars == 0) {
|
||||
close(client);
|
||||
|
||||
struct epoll_event ev;
|
||||
ev.events = EPOLLIN | EPOLLET;
|
||||
ev.data.fd = client;
|
||||
epoll_ctl(epfd, EPOLL_CTL_DEL, client, &ev);
|
||||
|
||||
DEC_COUNTFD;
|
||||
} else {
|
||||
//printf("recv numchars : %ld\n", numchars);
|
||||
}
|
||||
//serve_file(client, path);
|
||||
|
||||
}
|
||||
|
||||
#if 0
|
||||
#define HTML_PAGE "<HTML> \
|
||||
<TITLE>Index</TITLE> \
|
||||
<BODY> \
|
||||
<P>Welcome to J. David's webserver.\
|
||||
<H1>CGI demo \
|
||||
<FORM ACTION=\"color.cgi\" METHOD=\"POST\">\
|
||||
Enter a color: <INPUT TYPE=\"text\" NAME=\"color\">\
|
||||
<INPUT TYPE=\"submit\">\
|
||||
</FORM>\
|
||||
</BODY>\
|
||||
</HTML>"
|
||||
|
||||
#else
|
||||
#define HTML_PAGE "<!DOCTYPE html> \
|
||||
<html> \
|
||||
<head> \
|
||||
<title>Welcome to nginx!</title> \
|
||||
<style> \
|
||||
body { \
|
||||
width: 35em;\
|
||||
margin: 0 auto;\
|
||||
font-family: Tahoma, Verdana, Arial, sans-serif;\
|
||||
}\
|
||||
</style>\
|
||||
</head>\
|
||||
<body>\
|
||||
<h1>Welcome to nginx!</h1>\
|
||||
<p>If you see this page, the nginx web server is successfully installed and\
|
||||
working. Further configuration is required.</p>\
|
||||
\
|
||||
<p>For online documentation and support please refer to\
|
||||
<a href=\"http://nginx.org/\">nginx.org</a>.<br/>\
|
||||
Commercial support is available at\
|
||||
<a href=\"http://nginx.com/\">nginx.com</a>.</p>\
|
||||
\
|
||||
<p><em>Thank you for using nginx.</em></p>\
|
||||
</body>\
|
||||
</html>"
|
||||
#endif
|
||||
|
||||
void cat(int client)
|
||||
{
|
||||
|
||||
//char buf[1024] = HTML_PAGE;
|
||||
|
||||
int ret = send(client, HTML_PAGE, strlen(HTML_PAGE), 0);
|
||||
if (ret == -1) {
|
||||
printf("send : errno : %d\n", errno);
|
||||
} else {
|
||||
printf("cat send ret : %d\n", ret);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void error_die(const char *sc)
|
||||
{
|
||||
printf("%s\n", sc);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void headers(int client)
|
||||
{
|
||||
char buf[1024] = {0};
|
||||
char content[128] = {0};
|
||||
|
||||
sprintf(buf, "HTTP/1.0 200 OK\r\n");
|
||||
strcat(buf, SERVER_STRING);
|
||||
strcat(buf, "Content-Type: text/html\r\n");
|
||||
#if 0
|
||||
strcat(buf, "Transfer-Encoding: chunked\r\n");
|
||||
#else
|
||||
sprintf(content, "Content-Length: %ld\r\n", strlen(HTML_PAGE));
|
||||
strcat(buf, content);
|
||||
#endif
|
||||
strcat(buf, "\r\n");
|
||||
|
||||
strcat(buf, HTML_PAGE);
|
||||
|
||||
int ret = send(client, buf, strlen(buf), 0);
|
||||
if (ret == -1) {
|
||||
printf("send : errno : %d\n", errno);
|
||||
} else {
|
||||
//printf("headers send ret : %d\n", ret);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**********************************************************************/
|
||||
/* Send a regular file to the client. Use headers, and report
|
||||
* errors to client if they occur.
|
||||
* Parameters: a pointer to a file structure produced from the socket
|
||||
* file descriptor
|
||||
* the name of the file to serve */
|
||||
/**********************************************************************/
|
||||
void serve_file(int client)
|
||||
{
|
||||
headers(client);
|
||||
//cat(client);
|
||||
|
||||
}
|
||||
|
||||
#define MAX_EPOLLSIZE 10240
|
||||
|
||||
void server(void *arg) {
|
||||
|
||||
int fd = *(int *)arg;
|
||||
|
||||
int epfd = epoll_create(1);
|
||||
struct epoll_event events[MAX_EPOLLSIZE];
|
||||
|
||||
struct epoll_event ev;
|
||||
ev.events = EPOLLIN;
|
||||
ev.data.fd = fd;
|
||||
epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev);
|
||||
int acc = 1; //
|
||||
|
||||
while (1) {
|
||||
#if 0
|
||||
char lock = read_accept();
|
||||
if (lock == 1) { //lock
|
||||
ev.events = EPOLLIN;
|
||||
ev.data.fd = fd;
|
||||
epoll_ctl(epfd, EPOLL_CTL_DEL, fd, &ev);
|
||||
|
||||
write_accept(2); //add complete
|
||||
|
||||
} else if (acc == 0 && lock == 3) {
|
||||
ev.events = EPOLLIN;
|
||||
ev.data.fd = fd;
|
||||
epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev);
|
||||
|
||||
write_accept(0);
|
||||
}
|
||||
#endif
|
||||
int nready = epoll_wait(epfd, events, MAX_EPOLLSIZE, 1);
|
||||
if (nready == -1) {
|
||||
if (errno == EINTR) {
|
||||
printf("errno : EINTR\n");
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
for (i = 0;i < nready;i ++) {
|
||||
int sockfd = events[i].data.fd;
|
||||
if (sockfd == fd) {
|
||||
|
||||
struct sockaddr_in client_addr;
|
||||
memset(&client_addr, 0, sizeof(struct sockaddr_in));
|
||||
socklen_t client_len = sizeof(client_addr);
|
||||
#if 0
|
||||
if (get_countfd() % accept_disable == 999) {
|
||||
lock_accept();
|
||||
acc = 0;
|
||||
}
|
||||
char lock = read_accept();
|
||||
if (lock != 0 && lock != 3) continue;
|
||||
#endif
|
||||
if (lock()) {
|
||||
continue;
|
||||
}
|
||||
int clientfd = accept(sockfd, (struct sockaddr*)&client_addr, &client_len);
|
||||
unlock();
|
||||
|
||||
if (clientfd < 0) {
|
||||
if (errno == EAGAIN) {
|
||||
//printf("accept : EAGAIN\n");
|
||||
continue;
|
||||
} else if (errno == ECONNABORTED) {
|
||||
printf("accept : ECONNABORTED\n");
|
||||
|
||||
} else if (errno == EMFILE || errno == ENFILE) {
|
||||
printf("accept : EMFILE || ENFILE\n");
|
||||
}
|
||||
return ;
|
||||
}
|
||||
|
||||
INC_COUNTFD;
|
||||
|
||||
ntySetNonblock(clientfd);
|
||||
ntySetReUseAddr(clientfd);
|
||||
|
||||
struct epoll_event ev;
|
||||
ev.events = EPOLLIN | EPOLLET | EPOLLONESHOT;
|
||||
ev.data.fd = clientfd;
|
||||
epoll_ctl(epfd, EPOLL_CTL_ADD, clientfd, &ev);
|
||||
|
||||
}
|
||||
else if (events[i].events & EPOLLIN) {
|
||||
|
||||
accept_request(sockfd, epfd);
|
||||
#if 1
|
||||
//struct epoll_event ev;
|
||||
ev.events = EPOLLOUT | EPOLLET | EPOLLONESHOT;
|
||||
ev.data.fd = sockfd;
|
||||
epoll_ctl(epfd, EPOLL_CTL_MOD, sockfd, &ev);
|
||||
|
||||
//close(sockfd);
|
||||
#endif
|
||||
}
|
||||
else if (events[i].events & EPOLLOUT) {
|
||||
|
||||
serve_file(sockfd);
|
||||
|
||||
//close(sockfd);
|
||||
|
||||
//struct epoll_event ev;
|
||||
ev.events = EPOLLIN | EPOLLHUP | EPOLLRDHUP | EPOLLERR;
|
||||
ev.data.fd = sockfd;
|
||||
epoll_ctl(epfd, EPOLL_CTL_MOD, sockfd, &ev);
|
||||
|
||||
DEC_COUNTFD;
|
||||
|
||||
}
|
||||
else if (events[i].events & (EPOLLHUP|EPOLLRDHUP|EPOLLERR)) {
|
||||
|
||||
close(sockfd);
|
||||
|
||||
printf(" EPOLLHUP | EPOLLRDHUP\n");
|
||||
//struct epoll_event ev;
|
||||
ev.events = EPOLLIN | EPOLLET | EPOLLONESHOT;
|
||||
ev.data.fd = sockfd;
|
||||
epoll_ctl(epfd, EPOLL_CTL_DEL, sockfd, &ev);
|
||||
|
||||
DEC_COUNTFD;
|
||||
}
|
||||
}
|
||||
|
||||
// print_countfds();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int mulcore_entry(int begin_port) {
|
||||
|
||||
int i = 0;
|
||||
unsigned short base_port = begin_port;
|
||||
|
||||
unsigned short *port = calloc(1, sizeof(unsigned short));
|
||||
*port = base_port;
|
||||
server(port);
|
||||
|
||||
}
|
||||
|
||||
int process_bind(int fd) {
|
||||
|
||||
int num = sysconf(_SC_NPROCESSORS_CONF);
|
||||
|
||||
self_id = syscall(__NR_gettid);
|
||||
//printf("selfid --> %d\n", self_id);
|
||||
|
||||
cpu_set_t mask;
|
||||
|
||||
CPU_ZERO(&mask);
|
||||
CPU_SET(self_id % num, &mask);
|
||||
|
||||
sched_setaffinity(0, sizeof(mask), &mask);
|
||||
server(&fd);
|
||||
//mulcore_entry(9000);
|
||||
|
||||
}
|
||||
|
||||
int init_shmvalue(int num) {
|
||||
|
||||
global_shmid = shmget(IPC_PRIVATE, sizeof(shm_area), IPC_CREAT|0600);
|
||||
if (global_shmid < 0) {
|
||||
perror("shmget failed\n");
|
||||
return -1;
|
||||
}
|
||||
global_shmaddr = (shm_area*)shmat(global_shmid, NULL, 0);
|
||||
if (global_shmaddr == (shm_area*)-1) {
|
||||
perror("shmat addr error");
|
||||
return -1;
|
||||
}
|
||||
memset(global_shmaddr->totalfds, 0, TOTALFDS * sizeof(int));
|
||||
memset(global_shmaddr->cpu_lb, 0, TOTALFDS * sizeof(char));
|
||||
global_shmaddr->accept_mtx = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
short port = 9000;
|
||||
struct sockaddr_in client_name;
|
||||
socklen_t client_name_len = sizeof(client_name);
|
||||
|
||||
int fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (fd < 0) return -1;
|
||||
|
||||
ntySetNonblock(fd);
|
||||
ntySetReUseAddr(fd);
|
||||
|
||||
|
||||
struct sockaddr_in local, remote;
|
||||
local.sin_family = AF_INET;
|
||||
local.sin_port = htons(port);
|
||||
local.sin_addr.s_addr = INADDR_ANY;
|
||||
bind(fd, (struct sockaddr*)&local, sizeof(struct sockaddr_in));
|
||||
|
||||
listen(fd, 20);
|
||||
|
||||
int num = sysconf(_SC_NPROCESSORS_CONF);
|
||||
cpu_size = num;
|
||||
init_shmvalue(num);
|
||||
|
||||
int i = 0;
|
||||
pid_t pid=0;
|
||||
for(i = 0;i < num;i ++) {
|
||||
pid=fork();
|
||||
if(pid <= (pid_t) 0)
|
||||
{
|
||||
usleep(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#if 1
|
||||
if (pid > 0) {
|
||||
printf("ntyco_httpd server running ...\n");
|
||||
getchar();
|
||||
} else if (pid == 0) {
|
||||
process_bind(fd);
|
||||
}
|
||||
#else
|
||||
|
||||
|
||||
INC_COUNTFD;
|
||||
|
||||
INC_COUNTFD;
|
||||
print_countfds();
|
||||
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user