2013-08-19 3 views
0

У меня есть серверный сокет, принимающий соединения сокетов клиента. Принимать в потокеСокет не принимает подключения

создания сокета

int ServerSocket::CreateSocket(int port) 
{ 
listenfd = 0; 
struct sockaddr_in serv_addr; 
unsigned long iMode = 1; 

listenfd = socket(AF_INET, SOCK_STREAM, 0); 
memset(&serv_addr, '0', sizeof(serv_addr)); 

serv_addr.sin_family = AF_INET; 
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); 
serv_addr.sin_port = htons(port); 


ioctlsocket(listenfd, FIONBIO, &iMode); 

if (bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) 
{ 
    return 0; 
} 

if (listen(listenfd, 20) < 0) 
{ 
    return 0; 
} 

return listenfd; 
} 

Оправа Accept

void ServerSocket::AcceptClients_1(void * p) 
{ 
struct sockaddr_in cli_addr; 

// get a pointer to the ServerSocket object 
ServerSocket * pThis = (ServerSocket *)p; 
int iResult, cli_len; 
cli_len = sizeof(cli_addr); 
struct timeval tv = { 0, 1000 }; 
SOCKET s = pThis->GetSocket(); 
fd_set rfds; 

FD_ZERO(&rfds); 
FD_SET(s, &rfds); 

while (!pThis->ShutDownRequested) 
{ 
    iResult = select(s+1, &rfds, (fd_set *) 0, (fd_set *) 0, &tv); 
    if(iResult > 0) 
    { 
     // never comes here 
     SOCKET sclient = accept(s, (struct sockaddr *)&cli_addr, 
          &cli_len); 
    } 
    else if (iResult == 0) /// timeout 
    { 
     continue; 
    } 
    // error comes here are going to accept 2nd time 
    DWORD dwError = GetLastError(); 
    return; 
} 
} 

Этот код приходит на выбор(). Возвращает 0 первый раз, но второй раз всегда возвращает -1 с ошибкой 10022. Я не понимаю, почему. Пожалуйста помоги.

+1

сторона примечания, в вашем memset, ''0'' и' 0' - это не одно и то же. Кроме того, вы должны использовать 'WSAGetLastError', а не' GetLastError' – Hasturkun

ответ

0

Убедитесь, что pThis->GetSocket() правильно возвращенная listenfd. Кроме того, вы должны повторно инициализировать cli_len = sizeof(cli_addr); перед каждым вызовом до accept (это аргумент значения).

+0

Обратите внимание, что он не получает accept() даже один раз. Первый раз select() возвращает 0 и второе время -1 с кодом ошибки 10022 – user2696323

+0

Также делайте свои «FD_ZERO» и «FD_SET» в цикле перед выбором. – mark

+0

Спасибо, что решает. – user2696323

0

iResult = 0 не всегда означает таймаут, для неблокирующих сокетов вам нужно проверить WSAGetLastError и обработать некоторые коды ошибок, например WSAEWOULDBLOCK означает, что вам нужно ждать следующего события в этом сокете.

http://msdn.microsoft.com/en-us/library/windows/desktop/ms740668(v=vs.85).aspx

+0

Да, вы правы, но проблема в том, что я получаю ошибку 10022, а не WSAEWOULDBLOCK. Я изменил свой код, чтобы позаботиться о WSAEWOULDBLOCK, но это не решает проблему. – user2696323