TinyHttp

HTTP报文结构
TinyHttp_第1张图片
请求报文
TinyHttp_第2张图片
TinyHttp_第3张图片
TinyHttp_第4张图片

//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

你可能感兴趣的:(Socket)