while(m_severRun){
printf("ServerManager::eventAcceptLoop, epoll_wait\n");
int event_cnt = epoll_wait(m_epfd, m_events, EPOLL_SIZE, -1);
if(event_cnt == -1){
perror("epoll_wait error \n");
break;
}
for(int i=0; i<event_cnt; i++){
SocketClient *conn = reinterpret_cast<SocketClient *>(m_events[i].data.ptr);
if(conn->getFd() == m_serverSocket->getFd()){
printf("ServerManager::eventAcceptLoop, A Client has been connected \n");
struct sockaddr_in clnt_adr;
socklen_t adr_sz = sizeof(clnt_adr);
int clnt_sock = accept(m_serverSocket->getFd(), (struct sockaddr*)&clnt_adr, &adr_sz);
SocketClient* client = new SocketClient(clnt_sock);
if(!addClient(client))
break;
}
else{
if(m_events[i].events & EPOLLRDHUP){
printf("ServerManager::eventAcceptLoop, EPOLLRDHUP \n");
removeClient(conn);
close(conn->getFd());
continue;
}
if(m_events[i].events & EPOLLIN){
printf("ServerManager::eventAcceptLoop, EPOLLIN \n");
int recv = conn->recv();
if(recv <= 0){
removeClient(conn);
close(conn->getFd());
}
else{
printf("ServerManager::eventAcceptLoop, A message has been received \n");
vector<char> data = conn->getData();
addWork(conn, data);
}
}
if(m_events[i].events & EPOLLERR)
printf("ServerManager::eventAcceptLoop, EPOLLERR \n");
}
}//for loop end
}//while loop end
私はネットワークプログラミング(TCP)で作業していますが、私はこのコードを持っています。 epollを初めて使ったので、このデザインが正しいかどうかわかりません。また、スレッドプール(5つの子スレッド)を使用しています。私はepollからデータを読み込むたびにスレッドプールのキューに配置します。問題は、読み取り機能ではボトルネックの問題を見ることができるということです。読み出し機能でボトルネックの問題を伴うepollアーキテクチャの問題
、それはソケットを監視し、一定時間信号がない場合、それは、ソケットを閉じるために0を返すObserveSocket
int SocketClient::ObserveSock(int sock, int timeout){
printf("SocketClient::ObserveSock called\n");
fd_set reads;
int fd_max;
struct timeval _timeout;
FD_ZERO(&reads);
FD_SET(sock, &reads);
fd_max = sock + 1;
_timeout.tv_sec = timeout;
_timeout.tv_usec = 0;
return select(fd_max, &reads, 0, 0, &_timeout);
}
を呼び出します。私は予期せぬユーザーの切断やデータの破損を検出するためにこのコードが必要だと思っています(クライアントは100バイトを送信しましたが、サーバーは90バイトを受信した後、サーバーは到着しない最後の10バイトを待ちます)。
ボトルネックの問題とこれに関するアーキテクチャ上の問題をどのように修正できるか教えていただければ幸いです。
また、epollを使用し、例外処理について詳しく説明した良いチュートリアルを探します。
ありがとうございます。
のrecvの内部EDIT
は()それだけで読んで関数を呼び出すと、私は読む前に、私はObserveSocketを呼び出す機能
"読み取り機能ではObserveSocketを呼び出します" - どのような "読み取り"機能ですか?あなたはSocketClient :: recv()を意味しますか?あなたが提供していない関数にはあまりにも多くの呼び出しがあります... – Nemo