#include "common.h"
#include "taskline.h"

#define NTHREADS  4
#define SBUFSIZE   16

void toggle(int conn_sock,int hit);
void *handle_request(void *vargp);

task_line_t tlp;                    /* task pool: shared buffer of connected descriptors */

int main(int argc, char **argv) 
{
    int listen_sock, conn_sock, port,i; 
    struct sockaddr_in clientaddr; 
    struct hostent *hp;
    char *haddrp;
    int hit;
    task_t item;               //连接客户信息：socket和客户编号
    int nth[NTHREADS];
    
    socklen_t clientlen=sizeof(struct sockaddr_in);

    pthread_t tid; 

    if (argc != 2) {
	    fprintf(stderr, "usage: %s <port>\n", argv[0]);
	    exit(1);
    }
    
    listen_sock = open_listen_sock(port);
    if( listen_sock==-1) {
    	printf("端口号%d繁忙\n",port);
    	exit(1);
    }
    
    
    port = atoi(argv[1]);
    task_line_init(&tlp, SBUFSIZE);
    
    listen_sock = open_listen_sock(port);
    if( listen_sock==-1) {
    	printf("端口号%d繁忙\n",port);
    	exit(1);
    }
    
    for (i = 0; i < NTHREADS; i++)  {     /* Create worker threads */
            nth[i]=i;
	    pthread_create(&tid, NULL, handle_request, (void *)&nth[i]);
    }

    for (hit=1; ; hit++) { 
	    item.conn_sock = accept(listen_sock, (SA *) &clientaddr, &clientlen);
	    item.hit=hit;
	    
           /* determine the domain name and IP address of the client */
	    hp = gethostbyaddr((const char *)&clientaddr.sin_addr.s_addr, 
			   sizeof(clientaddr.sin_addr.s_addr), AF_INET);
	    haddrp = inet_ntoa(clientaddr.sin_addr);
	    printf("server connected to %s (%s)\n", hp->h_name, haddrp);

	    task_insert(&tlp, item);  /* Insert conn_sock in task pool */
    }
}

void *handle_request(void *vargp) 
{
    int tid=*(int*) vargp;
    task_t  item;
    pthread_detach(pthread_self()); 
    
    while (1) { 
	    item=task_remove(&tlp);   /* Remove a task from task line */
	    
	    printf("线程%d服务第%d个客户通信开始\n",tid,item.hit);
	    
	    toggle(item.conn_sock,item.hit);            /* Serve client */	   	    
	    close(item.conn_sock);
	    
	    printf("线程%d服务第%d个客户通信结束\n",tid,item.hit);
    }
}

void toggle(int conn_sock,int hit) 
{
    size_t n; int i,no=0;
    char buf[MAXLINE]; 

    while((n =recv(conn_sock, buf, MAXLINE,0))> 0) {
	printf("toggle服务器收到第%d个客户第%d个消息,长度为%d字节\n", hit,++no,(int)n);

        for(i=0; i<n; i++)
            if(isupper(buf[i])) 
                buf[i]=tolower(buf[i]);
            else if(islower(buf[i]))
                buf[i]=toupper(buf[i]);
               
	send (conn_sock, buf, n, 0);
    }
}
