- 论坛徽章:
- 0
|
代码是这样写的:当主线程发现有连接来时加入FD_SET,select到可读时,加一个读的任务到队列tasklist中,然后有3个子线程循环着从队列取任务read数据。
但是现在有个问题:只要客户端一发数据,服务端的tasklist.size()立马就上千,导致后续很多问题。
哪位热心朋友帮忙看看代码~~3Q、、
服务端:
- #include <unistd.h>
- #include <sys/types.h> /* basic system data types */
- #include <sys/socket.h> /* basic socket definitions */
- #include <netinet/in.h> /* sockaddr_in{} and other Internet defns */
- #include <arpa/inet.h> /* inet(3) functions */
- #include <stdlib.h>
- #include <errno.h>
- #include <stdio.h>
- #include <string.h>
- #include <fcntl.h>
- #include <sys/select.h>
- #include <pthread.h>
- #include <iostream>
- #include <list>
- #include <signal.h>
- using namespace std;
- pthread_mutex_t lock;
- enum falgrw{readflag = 0,writeflag};
- typedef struct{
- int fd;
- int op;
- }Task;
- void *func( void *arg );
- Task *create_task(int socket);
- int clientSockFds[FD_SETSIZE]={0};
- fd_set allset;
- list<Task> tasklist(0);
- int main()
- {
-
- int guo=0;
- pthread_t thread[3];
- for(guo=0;guo<3;guo++)
- {
- pthread_create(&thread[guo],NULL,func,NULL);
- }
-
- int listenfd = 0;
- int connfd = 0;
- int serverPort= 8888;
- int listenq = 5;
- socklen_t socklen = 0;
- int opt = 1;
- int nready = 0;
- int maxfd = 0;
- int maxi = -1;
- char buf[50]= {0};
- struct sockaddr_in cliaddr, servaddr;
- socklen = sizeof(struct sockaddr_in);
- memset(&servaddr, 0, sizeof(servaddr));
- memset(&cliaddr, 0, sizeof(cliaddr));
-
- servaddr.sin_family = AF_INET;
- servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
- servaddr.sin_port = htons(serverPort);
- listenfd = socket(AF_INET, SOCK_STREAM, 0);
- if (listenfd < 0)
- {
- perror("socket error");
- return -1;
- }
- if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (const char*)&opt, sizeof(opt)) < 0)
- {
- perror("setsockopt error");
- }
- if (bind(listenfd, (struct sockaddr *) &servaddr, socklen) < 0)
- {
- perror("bind error");
- return -1;
- }
- if (listen(listenfd, listenq) < 0)
- {
- perror("listen error");
- return -1;
- }
-
- FD_ZERO(&allset);
- FD_SET(listenfd, &allset);
- maxfd = listenfd;
- for (int j = 0; j< FD_SETSIZE; j++)
- {
- clientSockFds[j] = -1;
- }
-
- printf("echo server startup,listen on port:%d\n", serverPort);
- printf("max connection: %d\n", FD_SETSIZE);
- while(1)
- {
- fd_set rset = allset;
- nready = select(maxfd + 1, &rset, NULL, NULL, NULL);
- //printf("nready = %d\n",nready);
- if (nready < 0)
- {
- perror("select error");
- continue;
- }
- if (FD_ISSET(listenfd, &rset))
- {
- connfd = accept(listenfd, (struct sockaddr*) &cliaddr, &socklen);
- if (connfd < 0)
- {
- perror("accept error");
- continue;
- }
-
- sprintf(buf, "accept form %s:%d: connfd=%d\n", inet_ntoa(cliaddr.sin_addr), cliaddr.sin_port,connfd);
- printf(buf, "");
- int i=0;
- for (i = 0; i< FD_SETSIZE; i++)
- {
- if (clientSockFds[i] == -1)
- {
- clientSockFds[i] = connfd;
- break;
- }
- }
- if (i == FD_SETSIZE)
- {
- fprintf(stderr, "too many connection, more than %d\n", FD_SETSIZE);
- close(connfd);
- break;
- }
- if (connfd > maxfd)
- maxfd = connfd;
-
- FD_SET(connfd, &allset);
- }
- printf("main111() tasklist.size():[%d]--->Thread:%d\n\n",tasklist.size(),pthread_self());
- for(int m=0;m<1024 && clientSockFds[m] != -1 ;m++)
- {
- if (FD_ISSET(clientSockFds[m], &rset))
- {
- pthread_mutex_lock(&lock);
- Task *task = create_task(clientSockFds[m]);
- tasklist.push_back(*task);
-
- printf("main222() task->fd:%d--->tasklist.size():[%d]--->Thread:%d\n",task->fd,tasklist.size(),pthread_self());
- pthread_mutex_unlock(&lock);
- }
-
- }
- }
- close(listenfd);
- return 0;
- }
- Task *create_task(int socket)
- {
- Task *task = (Task *)malloc(sizeof(Task));
- task->fd=socket;
- task->op= readflag;
- return task;
- }
- void *func( void *arg )
- {
- char buffer[1024]={0};
- Task task;
- pthread_detach(pthread_self());
- while(1)
- {
- pthread_mutex_lock(&lock);
- if(tasklist.size()>0)
- {
-
- task = tasklist.front();
- tasklist.pop_front();
- printf("task.fd:%d----->tasklist.size():[%d]--->Thread:%d\n",task.fd,tasklist.size(),pthread_self());
- exit(0);
- int xxx=read(task.fd,buffer,sizeof(buffer));
- if(xxx==0)
- {
- printf("client %d close!\n",task.fd);
- FD_CLR(task.fd,&allset);
- close(task.fd);
- for (int i = 0; i< FD_SETSIZE; i++)
- {
- if (clientSockFds[i] == task.fd)
- {
- clientSockFds[i] = -1;
- break;
- }
- }
-
- }
- else if(xxx>0)
- {
- printf("fd:%d-->Thread:%d---->receive data:%s\n\n",task.fd,pthread_self(),buffer);
- }
- else
- {
- printf("wrong!!\n");
- FD_CLR(task.fd,&allset);
- close(task.fd);
- for (int i = 0; i< FD_SETSIZE; i++)
- {
- if (clientSockFds[i] == task.fd)
- {
- clientSockFds[i] = -1;
- break;
- }
- }
-
- }
-
- }
- pthread_mutex_unlock(&lock);
- sleep(1);
- }
- return 0;
- }
复制代码 客户端:
- #include <unistd.h>
- #include <sys/types.h> /* basic system data types */
- #include <sys/socket.h> /* basic socket definitions */
- #include <netinet/in.h> /* sockaddr_in{} and other Internet defns */
- #include <arpa/inet.h> /* inet(3) functions */
- #include <stdlib.h>
- #include <errno.h>
- #include <stdio.h>
- #include <string.h>
- #include <fcntl.h>
- #include <sys/select.h>
- #include <pthread.h>
- #include <iostream>
- #include <list>
- using namespace std;
- int main()
- {
- int cfd; /* 文件描述符 */
- int recbytes;
- int sin_size;
- char buffer[1024]={0};
- struct sockaddr_in s_add,c_add;
- unsigned short portnum=8888;
- printf("Hello,welcome to client !\r\n");
- cfd = socket(AF_INET, SOCK_STREAM, 0);
- if(-1 == cfd)
- {
- printf("socket fail ! \r\n");
- return -1;
- }
- printf("socket ok !\r\n");
-
- bzero(&s_add,sizeof(struct sockaddr_in));
- s_add.sin_family=AF_INET;
- s_add.sin_addr.s_addr= inet_addr("127.0.0.1");
- s_add.sin_port=htons(portnum);
- if(-1 == connect(cfd,(struct sockaddr *)(&s_add), sizeof(struct sockaddr)))
- {
- printf("connect fail !\r\n");
- return -1;
- }
- printf("connect ok !\r\n");
- int j=0;
- struct timeval tv;
- while(1)
- {
-
- memset(buffer,0,sizeof(buffer));
- sprintf(buffer,"%d%d",j,j);
- if(-1 == (recbytes = write(cfd,buffer,strlen(buffer)+1)))
- {
- printf("write data fail !\r\n");
- return -1;
- }
- printf("write ok.buffer=[%s]\n",buffer);
- sleep(1);
- j++;
-
- //test select
- tv.tv_sec = 0;
- tv.tv_usec = 1000;
- int ret = select(0, NULL, NULL, NULL, &tv);
- if (-1 == ret)
- {
- printf("wweeeeeee\n");
- }
-
- }
- close(cfd);
- return 0;
- }
复制代码 |
|