функ. для ожидание прихода данных.

Тема в разделе "WASM.NETWORKS", создана пользователем XshStasX, 16 сен 2009.

  1. XshStasX

    XshStasX New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2008
    Сообщения:
    991
    Как сделать так чтоб:
    после того как к серверу присоиденился клиент(протокол TCP) и мы создали для этого подключения новый поток.
    Сделать ожыдание в потоке(тоесть чтоб поток уснул пока не получить данные) о приходе неких даных от клиента...
     
  2. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    recv на блокирующем сокете.
     
  3. XshStasX

    XshStasX New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2008
    Сообщения:
    991
    Это как?)
    А нельзя что-то типа события на приход данных в порт сделать?
    и потом ждать это событие через WaitForSingleObject??
     
  4. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    По-умолчанию сокеты блокирующие, то есть блокируют поток, пока не придут данные или не отправятся.
     
  5. iZzz32

    iZzz32 Sergey Sfeli

    Публикаций:
    0
    Регистрация:
    3 сен 2006
    Сообщения:
    355
    Можно. WSAEventSelect. Но если для каждого клиента отдельный поток, почему не блокирующие вызовы?
     
  6. XshStasX

    XshStasX New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2008
    Сообщения:
    991
    У меня не блокирует поток...
    вот код:

    Код (Text):
    1. #include "stdafx.h"
    2. #include <winsock2.h>
    3. #pragma comment(lib,"WS2_32.lib");
    4. #include "windows.h"
    5. DWORD __stdcall ServFunc(void *p)
    6. {int s=(int)p;
    7. char buf[50]={0};
    8. while(1)
    9. {
    10.  recv(s,buf,50,0);
    11.  MessageBox(0,buf,buf,0);
    12. }
    13.  closesocket(s);
    14.     return 0;
    15. }
    16. int main(/*int argc, char* argv[]*/)
    17. {
    18.     WSADATA WSAData;
    19. int err=WSAStartup(MAKEWORD(1,1),&WSAData);
    20. SOCKADDR_IN sin;   
    21. sin.sin_family = AF_INET;  
    22. sin.sin_port = htons(3000);
    23. sin.sin_addr.s_addr = INADDR_ANY;
    24. int s = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    25. err = bind( s, (LPSOCKADDR)&sin, sizeof(sin) );
    26. err = listen(s,10);
    27. while(1)
    28. {
    29.     SOCKADDR_IN from;      
    30. int fromlen=sizeof(from);      
    31. int sclient = accept(s,(struct sockaddr*)&from, &fromlen);     
    32. DWORD i;
    33. CreateThread(0,0,ServFunc,(void*)sclient,0,&i);
    34. }; 
    35.     return 0;
    36. }
    хотя Recv возвращает 0...
     
  7. XshStasX

    XshStasX New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2008
    Сообщения:
    991
    И как узнать розмер пришедших данных на сервер?
     
  8. XshStasX

    XshStasX New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2008
    Сообщения:
    991
    Воопщем кажеться в чем то я розобрался)так что тему можна считать закрытой
     
  9. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Небось клиент сразу закрывает соединение. Жжошь товарищ^)
     
  10. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    XshStasX

    Блокирующий режим всегда можно выставить руками. MSDN: setsockopt.
     
  11. XshStasX

    XshStasX New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2008
    Сообщения:
    991
    и еще наверно вопросик, как узнать скоко данных можно получить через Recv?
    и еще вопрос, если я отправил из клиента к серверу сразу 500кб данных, то через Recv я их считаю за один раз, или они будут идти порциями?
     
  12. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    XshStasX
    Есть такая отличная штука, гугл называется.
     
  13. iZzz32

    iZzz32 Sergey Sfeli

    Публикаций:
    0
    Регистрация:
    3 сен 2006
    Сообщения:
    355
    XshStasX, google Network Programming for Microsoft Windows. Полностью можно не читать, если влом.
     
  14. nlnn

    nlnn New Member

    Публикаций:
    0
    Регистрация:
    8 сен 2009
    Сообщения:
    10
    XshStasX
    http://msdn.microsoft.com/en-us/library/aa365198(VS.85).aspx
     
  15. movdqu

    movdqu New Member

    Публикаций:
    0
    Регистрация:
    16 сен 2009
    Сообщения:
    33
    если сокет блокирующий:
    WSARecv - запишет столько сколько пришло в данный момент
    recv - надстройка над WSARecv и будет ожидать поступления всех данных
     
  16. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    movdqu
    Это что-то новое. А в Microsoft и IETF Вы уже об этом сообщили? А то судя по всему они там ещё не в курсе.
     
  17. movdqu

    movdqu New Member

    Публикаций:
    0
    Регистрация:
    16 сен 2009
    Сообщения:
    33
    Я думаю они знают, что несмотря на то что recv экспортируется из Ws2_32.dll, как и WSARecv, он работает через вызовы последнего.
     
  18. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    movdqu
    recv не вызывает WSARecv. И в случае TCP не ждёт, пока дойдут все данные, переданные send в качестве параметра на другой стороне. И не должен ждать, т.к. в этом смысл потокового протокола. Вообще рекомендуется вызывать recv в цикле, пока весь объём ожидаемых данных не будет получен.
     
  19. iZzz32

    iZzz32 Sergey Sfeli

    Публикаций:
    0
    Регистрация:
    3 сен 2006
    Сообщения:
    355
    l_inc, вызывает-вызывает :derisive:. И работают они одинаково (исключая поддержку в WSARecv нескольких буферов и overlapped IO). Но вот чтобы recv через узнавал, сколько клиент за один вызов отослал, да ещё ожидал, пока дойдёт – это да, повеселило. В случае TCP тут даже astral.dll не поможет, наверное…
     
  20. iZzz32

    iZzz32 Sergey Sfeli

    Публикаций:
    0
    Регистрация:
    3 сен 2006
    Сообщения:
    355
    А movdqu, видимо, говорил про MSG_PARTIAL, который поддерживает WSARecv. recv его действительно не поддерживает и возвращает WSAEMSGSIZE. А WSARecv (если протокол дейтаграммный) поймёт и вернёт кусок дейтаграммы.
    Код (Text):
    1. int recv (SOCKET s, char * buf, int len, int flags)
    2. {
    3.   WSABUF            tmpbuf = { len, buf };
    4.   DWORD             num;
    5.   DWORD             xflags = flags;
    6.   int               r;
    7.  
    8.   if ((r = WSARecv(s, &tmpbuf, 1, &num, &xflags, NULL, NULL)) == -1)
    9.     return -1;
    10.  
    11.   if (flags & MSG_PARTIAL)
    12.   {
    13.     SetLastError(WSAEMSGSIZE);
    14.     return -1;
    15.   }
    16.  
    17.   return num;
    18. }
    Как-то так)