Objective-C最简单的http服务器,只获取url请求部分
稍作修改可以同时兼容linux
#include <sys/socket.h>
#include <netinet/in.h>
#define BUFFER_SIZE 4096
#define PORT_BEG 2000
#define PORT_END 2100
char bundleid[128] = "com.lichao.test.test";
void handle(char* ibuf, int ilen, char* obuf, int olen) {
NSLog(@"%s", ibuf);
strcpy(obuf, "ok");
}
void* start_server() {
struct sockaddr_storage connector;
struct sockaddr_in address;
socklen_t addr_size = sizeof(connector);
int sock = socket(AF_INET, SOCK_STREAM, 0);
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
for (int port = PORT_BEG; port < PORT_END; port++) {
address.sin_port = htons(port);
if (0 == bind(sock, (struct sockaddr *)&address, sizeof(address))) {
NSLog(@"simpleserver:%s bind port %d", bundleid, port);
listen(sock, 1);
while (true) {
int accsock = accept(sock, (struct sockaddr *)&connector, &addr_size);
if (accsock > 0) {
char irawbuf[BUFFER_SIZE], orawbuf[BUFFER_SIZE], obuf[BUFFER_SIZE], ibuf[BUFFER_SIZE];
memset(ibuf, 0, BUFFER_SIZE);
memset(obuf, 0, BUFFER_SIZE);
memset(irawbuf, 0, BUFFER_SIZE);
memset(orawbuf, 0, BUFFER_SIZE);
if (recv(accsock, irawbuf, BUFFER_SIZE, 0) > 0) {
char* p1 = strchr(irawbuf, ' ') + 1;
char* p2 = strchr(p1, ' ');
memcpy(ibuf, p1, p2 - p1);
handle(ibuf, BUFFER_SIZE, obuf, BUFFER_SIZE);
// HTTP/1.1 404 Not Found\r\nContent-Length: 0
sprintf(orawbuf, "HTTP/1.1 200 OK\r\nContent-Length: %lu\r\n\r\n%s", strlen(obuf), obuf);
send(accsock, orawbuf, strlen(orawbuf) + 1, 0);
close(accsock);
}
}
}
break;
}
}
return 0;
}
int main(int argc, char * argv[]) {
pthread_t tid;
pthread_create(&tid, 0, (void* (*)(void*))start_server, 0);
}
测试:
curl -s x.x.x.x:2000/test
=>test
同样的,如果要构造一个daemon类型的后台服务器,只需要做少许改动:
#include <dlfcn.h>
#include <netinet/in.h>
#include <pthread.h>
#include <stdio.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <sys/types.h>
#include <sys/utsname.h>
#include <unistd.h>
#define MASTER
#define MASTER_PORT 2000
#define SLAVE_PORT_BEG 2001
#define SLAVE_PORT_END 2100
#define BUFFER_SIZE 65536
void handle(char* ibuf, int ilen, char* obuf, int olen) {
strcpy(obuf, ibuf);
}
void* start_server() {
struct sockaddr_storage connector;
struct sockaddr_in address;
socklen_t addr_size = sizeof(connector);
int sock = socket(AF_INET, SOCK_STREAM, 0);
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
int port = -1;
#ifdef MASTER
for (port = MASTER_PORT; port < MASTER_PORT + 1; port++) {
#else
for (port = SLAVE_PORT_BEG; port < SLAVE_PORT_END; port++) {
#endif
address.sin_port = htons(port);
if (0 == bind(sock, (struct sockaddr *)&address, sizeof(address))) {
NSLog(@"simpleserver:bind port %d", port);
listen(sock, 1);
while (true) {
int accsock = accept(sock, (struct sockaddr *)&connector, &addr_size);
if (accsock > 0) {
char irawbuf[BUFFER_SIZE], orawbuf[BUFFER_SIZE], obuf[BUFFER_SIZE], ibuf[BUFFER_SIZE];
memset(ibuf, 0, BUFFER_SIZE);
memset(obuf, 0, BUFFER_SIZE);
memset(irawbuf, 0, BUFFER_SIZE);
memset(orawbuf, 0, BUFFER_SIZE);
if (recv(accsock, irawbuf, BUFFER_SIZE, 0) > 0) {
char* p1 = strchr(irawbuf, ' ') + 2;
char* p2 = strchr(p1, ' ');
memcpy(ibuf, p1, p2 - p1);
handle(ibuf, BUFFER_SIZE, obuf, BUFFER_SIZE);
// HTTP/1.1 404 Not Found\r\nContent-Length: 0
sprintf(orawbuf, "HTTP/1.1 200 OK\r\nContent-Length: %lu\r\n\r\n%s", strlen(obuf), obuf);
send(accsock, orawbuf, strlen(orawbuf) + 1, 0);
close(accsock);
}
}
}
}
}
exit(0);
}
int main(int argc, char **argv, char **envp) {
pid_t ppid = getpid();
pid_t p = fork();
if (p == 0) { // child process
kill(ppid, SIGKILL); // 变成daemon
ppid = getpid();
p = fork();
if (p == 0) {
kill(ppid, SIGKILL);
pthread_t tid;
pthread_create(&tid, 0, (void* (*)(void*))start_server, 0);
pthread_detach(tid);
getchar();
}
}
sleep(1000);
}
网友评论