Linux网络编程-并发HTTP服务器
主要模块
dataType
1.StringMap
链表实现的Map
StringMap* createStringMap ();
void resolvePair (StringMap *map, char *raw, int len, char splitCharacter);
void resolveMultiPairs (StringMap *map, char *raw, int len, char splitCharacter, char pairSplitCharacter);
void addPair (StringMap *map, char *key, char *value);
char* getValue (StringMap *map, char *key);
void removePair (StringMap *map, char *key);
void outputMap (StringMap *map);
void destroyStringMap (StringMap *map, int freeCompletely);
2.BufList
一个缓冲区链表,方便存储多次socket读入的数据
BufList* createBufList (int blockSize);
char* addBuf (BufList *bufList);
char* getBuf (BufList *bufList, int index);
void removeBuf (BufList *bufList, int index);
void destroyBufList (BufList *bufList);
char* substractData (BufList *bufList, BufBlockPos start, BufBlockPos end);
threadPool
互斥锁实现的线程池
ThreadPool* createThreadPool (int maxThreadNum);
void submitTask (ThreadPool *pool, void *(*task) (void *arg), void *arg);
int destroyThreadPool (ThreadPool *pool);
http
http协议实现
1.Request
Request* createRequest ();
Request* substractRequest (int sockFd);
void outputRequest (Request *request);
void destroyRequest (Request *request);
2.Response
Response* createResponse ();
void addHeader (Response *response, char *name, char *value);
void appendContent (Response *response, char *src, int len);
char* serialize (Response *response, int *len);
void destroyResponse (Response *response);
3.Dispatcher
Dispatcher* createDispatcher ();
void registerHandler (Dispatcher *dispatcher, void* (*handler) (Request *, Response *));
void dispatch (Dispatcher *dispatcher, int sockFd);
void destroyDispatcher (Dispatcher *dispatcher);
主要代码
#define SERVER_IP "0.0.0.0"
#define SERVER_PORT 8000
#define CONCURRENT_NUM 10
ThreadPool *threadPool;
Dispatcher *dispatcher;
// 响应HTTP请求
void* handler (Request *req, Response *rep) {
rep->statusCode = 200;
appendContent (rep, "<h1>Hello, World!</h1>", 22);
return NULL;
}
// 包装dispatch函数,用作submitTask的参数
void* handlerAdapter (void *arg) {
int sockFd = *(int*) arg;
dispatch (dispatcher, sockFd); // 分发给handler处理
close (sockFd);
free (arg);
return NULL;
}
int main(int argn, char **argv) {
threadPool = createThreadPool (CONCURRENT_NUM);
dispatcher = createDispatcher ();
registerHandler (dispatcher, handler); // 注册HTTP处理器
int serverFd, connFd, ret;
socklen_t len;
char ip[40] = { 0 };
struct sockaddr_in serverAddr, clientAddr;
// 创建socket
serverFd = socket (AF_INET, SOCK_STREAM, 0);
if (serverFd < 0) {
printf ("[hyper-server] socket error: %s\n", strerror (errno));
exit (-1);
}
bzero (&serverAddr, sizeof (clientAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons (SERVER_PORT);
inet_pton(AF_INET, SERVER_IP, &serverAddr.sin_addr);
// 绑定地址
ret = bind (serverFd, (struct sockaddr*) &serverAddr, sizeof (serverAddr));
if (ret != 0) {
close (serverFd);
printf ("[hyper-server] bind error: %s\n", strerror (errno));
exit (-1);
}
// 开始监听
ret = listen (serverFd, 5);
if (ret != 0) {
close (serverFd);
printf ("[hyper-server] listen error: %s\n", strerror (errno));
exit (-1);
}
printf ("[hyper-server] startup finished on %s:%d\n", SERVER_IP, SERVER_PORT);
len = sizeof (clientAddr);
bzero (&clientAddr, sizeof (clientAddr));
while (TRUE) {
len = sizeof (clientAddr);
connFd = accept (serverFd, (struct sockaddr*) &clientAddr, &len);
printf("[hyper-server] client ip: %s\n", inet_ntop(AF_INET, &clientAddr.sin_addr, ip, sizeof(ip)));
if (connFd < 0) printf ("[hyper-server] accept error: %s\n", strerror (errno));
else submitTask (threadPool, handlerAdapter, u_intcpy (connFd)); // 提交任务到线程池,u_intcpy返回一个int指针,指向connFd的一个拷贝
}
close (serverFd);
destroyDispatcher (dispatcher);
destroyThreadPool (threadPool);
return 0;
}
性能测试
ab -n 5000 -c 1000 http://localhost:8000/
在将测试请求数设置为7000以上时,测试无法通过,待完善。