HTTP报文结构
请求报文
//client
#include
#include
#include
#include
#include
#include
#include
void show_info(int connfd){
struct sockaddr_in local_addr;
bzero(&local_addr,sizeof(local_addr));
socklen_t local_addr_len = sizeof(local_addr);
getsockname(connfd,(struct sockaddr*)&local_addr,&local_addr_len);
printf("client local %s:%d\n",
inet_ntoa(local_addr.sin_addr),ntohs(local_addr.sin_port));
struct sockaddr_in peer_addr;
bzero(&peer_addr,sizeof(peer_addr));
socklen_t peer_addr_len = sizeof(peer_addr);
getpeername(connfd,(struct sockaddr*)&peer_addr,&peer_addr_len);
printf("clinet peer%s:%d\n",
inet_ntoa(peer_addr.sin_addr),ntohs(peer_addr.sin_port));
}
int main(int argc,char* argv[]){
if(3 != argc){
printf("usage:%s <#port> \n",argv[0]);
return 1;
}
//建立套接字
int connfd = socket(AF_INET,SOCK_STREAM,0);
if(-1 == connfd){
perror("socket err");
return 1;
}
struct sockaddr_in remote_addr;
bzero(&remote_addr,sizeof(remote_addr));
remote_addr.sin_family = AF_INET;
remote_addr.sin_addr.s_addr = inet_addr(argv[1]);
remote_addr.sin_port = htons(atoi(argv[2]));
//连接到远方主机端口
if(-1 == connect(connfd,(struct sockaddr*)&remote_addr,sizeof(remote_addr))){
perror("connect err");
return 1;
}
show_info(connfd);
char buf[BUFSIZ];
bzero(buf,BUFSIZ);
while(fgets(buf,BUFSIZ,stdin) != NULL){
write(connfd,buf,strlen(buf)+1);
printf("client send:%s\n",buf);
bzero(buf,BUFSIZ);
// sendfile(fd,connfd,NULL,);
if(-1 == read(connfd,buf,BUFSIZ)){
perror("read err");
return 1;
}
printf("client recv:%s\n",buf);
}
close(connfd);
}
//server
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
struct func_t_arg {
struct pollfd* poll_fd;
int i;
int poll_fd_cnt;
char* work_dir;
};
class ThreadPool
{
typedef void (*func_t)(struct pollfd* poll_fd,int i,int poll_fd_cnt,const char* work_dir);
public:
ThreadPool(size_t count):destroy(false)
{
// 初始化互斥锁和条件变量
pthread_mutex_init(&mutex,NULL);
pthread_cond_init(&cond,NULL);
// 初始化线程组
for(int i=0; i(&ThreadPool::Route),this);
threads.push_back(tid);
}
}
~ThreadPool()
{
// 通知线程退出
destroy = true;
//让阻塞的线程不再阻塞,pthread_join是等待回收线程的。
pthread_cond_broadcast(&cond);
for(vector::iterator it = threads.begin(); it != threads.end(); it++) {
pthread_join(*it,NULL);
}
// 销毁互斥锁和条件变量
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond);
}
void AddJob(func_t func,struct func_t_arg arg)
{
pthread_mutex_lock(&mutex);
tasks.push(func);
args.push(arg);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
}
private:
static void Route(ThreadPool* pPool)
{
for(;;) {
pthread_mutex_lock(&(pPool->mutex));
// 如果没有任务等待
while(pPool->tasks.empty() && !pPool->destroy) {
pthread_cond_wait(&(pPool->cond),&(pPool->mutex));
}
// 线程退出
if(pPool->destroy) {
pthread_mutex_unlock(&(pPool->mutex));
break;
}
// 获取任务
func_t task = pPool->tasks.front();
pPool->tasks.pop();
struct func_t_arg arg = pPool->args.front();
pPool->args.pop();
pthread_mutex_unlock(&(pPool->mutex));
// 执行任务
task(arg.poll_fd,arg.i,arg.poll_fd_cnt,arg.work_dir);
}
}
private:
vector threads; ///< 线程组
queue tasks; ///< 任务队列
queue args; ///< 参数队列
pthread_mutex_t mutex;
pthread_cond_t cond;
bool destroy; ///< 线程池销毁标志
};
//char* work_dir = NULL;
//struct pollfd poll_fd[INR_OPEN_MAX];
void show_info(int connfd)
{
struct sockaddr_in local_addr;
bzero(&local_addr,sizeof(local_addr));
socklen_t local_addr_len = sizeof(local_addr);
getsockname(connfd,(struct sockaddr*)&local_addr,&local_addr_len);
printf("server local %s:%d\n",inet_ntoa(local_addr.sin_addr),ntohs(local_addr.sin_port));
struct sockaddr_in peer_addr;
bzero(&peer_addr,sizeof(peer_addr));
socklen_t peer_addr_len = sizeof(peer_addr);
getpeername(connfd,(struct sockaddr*)&peer_addr,&peer_addr_len);
printf("server peer %s:%d\n",inet_ntoa(peer_addr.sin_addr),ntohs(peer_addr.sin_port));
}
void Handle(struct pollfd* poll_fd,int i,int poll_fd_cnt,const char* work_dir)
{
char buf[BUFSIZ];
for(;;) {
bzero(buf,BUFSIZ);
ssize_t len;
if((len = read(poll_fd[i].fd,buf,BUFSIZ-1)) == -1) {
perror("read err");
pthread_exit((void*)1);
}
if(0 == len) {
printf("close %d\n",poll_fd[i].fd);
printf("%d vs %d\n",poll_fd[i].revents,poll_fd[i].revents);
close(poll_fd[i].fd);
printf("%d vs %d\n",poll_fd[i].revents,poll_fd[i].revents);
memcpy(poll_fd+i,poll_fd+i+1,poll_fd_cnt-i-1);
poll_fd_cnt--;
i--;//数组发生变化,重新判断i的fd
break;
}
printf("server recv:%s\n",buf);
// 报文解析,获取URI
int url_start = 0;
int url_end = 0;
for(int j=0; j <#port> \n",argv[0]);
return 1;
}
char* work_dir = NULL;
work_dir = argv[3];
int listenfd = socket(AF_INET,SOCK_STREAM,0);
if(-1 == listenfd) {
perror("listenfd open err");
return 1;
}
printf("socket create OK\n");
int flag = 1;
setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&flag,sizeof(flag));
struct sockaddr_in local_addr;
bzero(&local_addr,sizeof(local_addr));
local_addr.sin_family = AF_INET;
local_addr.sin_addr.s_addr = inet_addr(argv[1]);
local_addr.sin_port = htons(atoi(argv[2]));
if(-1 == bind(listenfd,(struct sockaddr*)&local_addr,sizeof(local_addr))) {
perror("bind err");
return 1;
}
printf("bind OK\n");
if(-1 == listen(listenfd,10)) {
perror("listen err");
return 1;
}
printf("listen OK\n");
struct pollfd poll_fd[INR_OPEN_MAX];
poll_fd[0].fd = listenfd;
poll_fd[0].events = POLLRDNORM;
size_t poll_fd_cnt = 1;
for(;;) {
if(-1 != poll(poll_fd,poll_fd_cnt,-1)) {
if(poll_fd[0].revents == POLLRDNORM) {
printf("accept listenfd\n");
int connfd = accept(listenfd,NULL,NULL);
if(-1 == connfd) {
perror("accept err");
} else {
if(poll_fd_cnt+1 == INR_OPEN_MAX) {
fprintf(stderr,"connfd size over %d",INR_OPEN_MAX);
close(connfd);
} else {
poll_fd[poll_fd_cnt].fd = connfd;
poll_fd[poll_fd_cnt].events = POLLRDNORM;
poll_fd_cnt++;
}
}
}
//初始化线程池
ThreadPool pool(3);
int i;
for(i=1; i