2016-11-16 2 views
-4

Я сделал окно, используя API Win32, и он должен ввести цикл сообщений:Windows, цикл обработки сообщений и цикл сервера

while (GetMessage(&msg, nullptr, 0, 0)) 
{ 
    TranslateMessage(&msg); 
    DispatchMessage(&msg); 
} 

Как создать сокет-сервер и начать получать клиентов, если мой основной поток обрабатывать сообщения пользовательского интерфейса?

Я попытался положить весь код сервера в потоке с использованием CreateThread() из WinMain(), но он просто падает с ошибкой:

Exception thrown at 0x00000000 in test.exe: 0xC0000005: Access violation executing location 0x00000000.

Вот код резьбы:

DWORD WINAPI ThreadProc(LPVOID lpParameter) 
{ 
    // Initialize Winsock 
    WSADATA wsaData; 
    auto iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); 
    if (iResult != 0) { 
     printf("WSAStartup failed with error: %d\n", iResult); 
     return EXIT_FAILURE; 
    } 

    addrinfo hints; 
    ZeroMemory(&hints, sizeof(hints)); 
    hints.ai_family = AF_INET; 
    hints.ai_socktype = SOCK_STREAM; 
    hints.ai_protocol = IPPROTO_TCP; 
    hints.ai_flags = AI_PASSIVE; 

    // Resolve the server address and port 
    PADDRINFOA pAddrInfo = nullptr; 
    iResult = getaddrinfo(nullptr, PORT, &hints, &pAddrInfo); 
    if (iResult != 0) { 
     printf("getaddrinfo failed with error: %d\n", iResult); 
     WSACleanup(); 
     return EXIT_FAILURE; 
    } 

    while (true) { 
     // Create a SOCKET for connecting to server 
     auto ListenSocket = socket(pAddrInfo->ai_family, pAddrInfo->ai_socktype, pAddrInfo->ai_protocol); 
     if (ListenSocket == INVALID_SOCKET) { 
      printf("socket failed with error: %ld\n", WSAGetLastError()); 
      freeaddrinfo(pAddrInfo); 
      WSACleanup(); 
      return EXIT_FAILURE; 
     } 

     // Setup the TCP listening socket 
     iResult = bind(ListenSocket, pAddrInfo->ai_addr, static_cast<int>(pAddrInfo->ai_addrlen)); 
     if (iResult == SOCKET_ERROR) { 
      printf("bind failed with error: %d\n", WSAGetLastError()); 
      freeaddrinfo(pAddrInfo); 
      closesocket(ListenSocket); 
      WSACleanup(); 
      return EXIT_FAILURE; 
     } 

     freeaddrinfo(pAddrInfo); 

     iResult = listen(ListenSocket, SOMAXCONN); 
     if (iResult == SOCKET_ERROR) { 
      printf("listen failed with error: %d\n", WSAGetLastError()); 
      closesocket(ListenSocket); 
      WSACleanup(); 
      return EXIT_FAILURE; 
     } 

     // Accept a client socket 
     auto ClientSocket = accept(ListenSocket, nullptr, nullptr); 
     if (ClientSocket == INVALID_SOCKET) { 
      printf("accept failed with error: %d\n", WSAGetLastError()); 
      closesocket(ListenSocket); 
      WSACleanup(); 
      return EXIT_FAILURE; 
     } 

     // No longer need server socket 
     closesocket(ListenSocket); 

     // Receive until the peer shuts down the connection 
     for (;;) 
     { 
      char recvbuf[1] = { 0 }; 
      auto cbLen = recv(ClientSocket, recvbuf, sizeof(recvbuf), 0); 

      if (cbLen > 0) { 
       if (recvbuf[0] == 0xDA) 
       { 
        Hide(); 
       } 

       continue; 
      } 
      else if (cbLen == 0) { 
       printf("Connection closing...\n"); 
       break; 
      } 
      else { 
       printf("recv failed with error: %d\n", WSAGetLastError()); 
       closesocket(ClientSocket); 
       WSACleanup(); 
       return EXIT_FAILURE; 
      } 
     } 

     // shutdown receive operations since we're done 
     iResult = shutdown(ClientSocket, SD_RECEIVE); 
     if (iResult == SOCKET_ERROR) { 
      printf("shutdown failed with error: %d\n", WSAGetLastError()); 
      closesocket(ClientSocket); 
      WSACleanup(); 
      return EXIT_FAILURE; 
     } 

     // cleanup 
     closesocket(ClientSocket); 
    } 
    WSACleanup(); 

    return 0; 
} 
+1

Какова остальная часть вашего кода (я не вижу ThreadProc и CreateThread)? Где вы получаете исключение? – z32a7ul

+0

Я вижу исключение, брошенное на 0x00000000 - это ваш ThreadProc NULL? Я имею в виду, когда вы вызываете CreateThread, каково точное значение параметра, указывающего начальный адрес нового потока? – z32a7ul

+0

В вашем коде есть дефект, но вы не указали соответствующий код. –

ответ

0

Это очень запутанный вопрос, поскольку он задает один вопрос в названии, но в содержании рассматривается другая проблема (потоки сбой).

Для решения основного вопроса: Microsoft действительно добавила способ обработки сообщений сокетов в дружественном виде в графическом интерфейсе: WSAAsyncSelect. Это отправит события сокета как сообщения в очередь сообщений приложений - обычно для обработки сообщений создается невидимое окно.

+0

Возможно, у вас возникла просьба написать этот ответ, но он не отвечает на заданный вопрос. –

+0

Первая фактическая строка, которая является вопросом в сообщении, буквально: «Как создать сервер сокетов и начать прием клиентов, если мой основной поток обрабатывает сообщения пользовательского интерфейса?» Что - по общему признанию - затем сопровождалось большим количеством шума о потоках. –

Смежные вопросы