Таймаут ожидания коннекта

Тема в разделе "WASM.WIN32", создана пользователем perdimonokl, 27 июл 2008.

  1. perdimonokl

    perdimonokl New Member

    Публикаций:
    0
    Регистрация:
    18 сен 2007
    Сообщения:
    38
    Народ никак не могу додуматься уже 2-ой день. Вот код
    Код (Text):
    1. #include <windows.h>
    2. #include <stdio.h>
    3.  
    4. #pragma comment(lib,"ws2_32.lib")
    5.  
    6. #pragma comment(linker,"/entry:main")
    7.  
    8. int main(int argc, char* argv[])
    9. {
    10.   WSADATA wsaData;
    11.   SOCKET sockid,consock;
    12.   struct sockaddr_in idsin;
    13.   int i=0;
    14.  
    15.   idsin.sin_family = AF_INET;
    16.   idsin.sin_addr.s_addr = 0;
    17.   idsin.sin_port = htons(4444);
    18.  
    19.   i = sizeof(idsin);
    20.  
    21.   WSAStartup(MAKEWORD(2,2), &wsaData);
    22.   sockid = socket(AF_INET, SOCK_STREAM, 0);
    23.   if (sockid == INVALID_SOCKET) { printf("Can't create socket...\n"); return 0; }
    24.   bind(sockid,(struct sockaddr *)&idsin, i);
    25.   listen(sockid, 10);
    26.  
    27.   while (1)
    28.   {
    29.       consock = accept(sockid, (struct sockaddr *)&idsin, &i);
    30.       if (consock != INVALID_SOCKET)
    31.       {
    32.           MessageBox(NULL,"Connected to...","title",MB_OK);
    33.           break;
    34.       }
    35.      Sleep(500);
    36.   }
    37.  
    38.   return 0;
    39. }
    Никак не могу написать, чтобы если в течение 5 секнуд не пришло коннекта на забинденный порт то закрывать сокет. Все мля перепробовал и какие тока извраты не делал так и не понял как сделать. Народ помогите с решением проблемы, код привел без лишнего бреда который я там накодел, чтобы легко можно было его исправить =)
     
  2. Vilco

    Vilco Vitaly

    Публикаций:
    0
    Регистрация:
    5 мар 2007
    Сообщения:
    190
    Адрес:
    Nsk, Russia
    Выносишь цикл ожидания в другой тред, создаешь событие, в основном треде вставляешь вызов WaitForSingleObject(hEvent, 5000), в новом потоке, по выходу из цикла инициируешь эвент, примерно так:
    hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    hThrd = CreateThread(..);
    if (WaitForSingleObject(hEvent, 5000)==WAIT_TIMEOUT)
    {
    MessageBox(NULL,"Timeout","title",MB_OK);
    return ..;
    }
    (это вместо цикла и listen, сам по ситуации смотри не хочется вникать; цикл выносишь в функцию потока)
     
  3. Com[e]r

    Com[e]r Com[e]r

    Публикаций:
    0
    Регистрация:
    20 апр 2007
    Сообщения:
    2.624
    Адрес:
    ого..
    протев, есть для этого команды уровня ioctlsocket( sock , FIONBIO, "\x01\x00\x00\x00" )//тока нонблокин
    и FD_SET(..,..)
     
  4. perdimonokl

    perdimonokl New Member

    Публикаций:
    0
    Регистрация:
    18 сен 2007
    Сообщения:
    38
    Угу спасибо за советы. Не так то просто было разобраться но вроде получилось =) Тоже сначала с эвентами подсказали сделать но как то эту идею отложил я на потом. Вот код
    Код (Text):
    1. #include <windows.h>
    2. #include <stdio.h>
    3.  
    4. #pragma comment(lib,"ws2_32.lib")
    5.  
    6. #pragma comment(linker,"/entry:main")
    7.  
    8. #define PORT 4444
    9.  
    10. int main(int argc, char* argv[])
    11. {
    12.   WSADATA wsaData;
    13.   SOCKET sockid,consock;
    14.   struct sockaddr_in idsin;
    15.   struct timeval tv;
    16.   fd_set sock;
    17.   unsigned long on_sock = 1,off_sock = 0;
    18.   int i=0;
    19.  
    20.   ZeroMemory(&tv,sizeof(tv));
    21.  
    22.   WSAStartup(MAKEWORD(2,2), &wsaData);
    23.  
    24.   i = sizeof(idsin);
    25.   tv.tv_sec = 5;
    26.  
    27.   idsin.sin_family = AF_INET;
    28.   idsin.sin_addr.s_addr = inet_addr("127.0.0.1");
    29.   idsin.sin_port = htons(PORT);
    30.  
    31.   sockid = socket(AF_INET, SOCK_STREAM, 0);
    32.  
    33.   if (sockid == INVALID_SOCKET) { printf("Can't create socket...\n"); return 0; }
    34.  
    35.   ioctlsocket(sockid, FIONBIO,&on_sock);
    36.   bind(sockid,(struct sockaddr *)&idsin, i);
    37.   listen(sockid, 10);
    38.  
    39.   FD_ZERO(&sock);
    40.   FD_SET(sockid,&sock);
    41.    
    42.   while (1)
    43.   {
    44.       consock = accept(sockid, (struct sockaddr *)&idsin, &i);
    45.       if(select(sockid+1, &sock, NULL, NULL, &tv )==0)
    46.       {
    47.           printf("\nConnection timed out in %d sec...\n",tv.tv_sec);
    48.           break;
    49.       }
    50.       if (consock != INVALID_SOCKET)
    51.       {
    52.           printf("\nClient connected...\n");
    53.           break;
    54.       }
    55.      Sleep(1000);
    56.   }
    57.  
    58.   ioctlsocket(sockid, FIONBIO, &off_sock);
    59.   closesocket(sockid);
    60.   WSACleanup();
    61.  
    62.   return 0;
    63. }
    Цикл и Sleep можно убрать вообще но и так тоже работает. Может кому и пригодится кодес =)
     
  5. Com[e]r

    Com[e]r Com[e]r

    Публикаций:
    0
    Регистрация:
    20 апр 2007
    Сообщения:
    2.624
    Адрес:
    ого..
    наш человек! мсрем тоже так делал! .)
    а слип оставь на 10мс, ибо если переглючит всех, то проц не будет грузиться со всей системой сокетов.