Winsock2: «слушай» возвращается рано

0

Я новичок в использовании winsock2 и собрал следующий код для сервера, который я пытаюсь использовать для отправки строки клиенту, который я запускаю на том же компьютере (подключение к 127.0.0.1 с тем же портом поскольку сервер настроен на прослушивание).

Я использую MinGW, если это имеет значение.

Проблема, с которой я сталкиваюсь, заключается в том, что listen(), кажется, заканчивается раньше, но возвращает код успеха. Это проблема, потому что тогда, когда accept() вызывается, кажется, что он блокируется навсегда. Это событие происходит независимо от того, выполняю ли я клиентскую программу, и я пытался запустить клиентскую программу до и после, но это, похоже, не влияет на нее.

// -1: "Could not initialize WSA."
// -2: "Could not create listener socket."
#define WIN32_LEAN_AND_MEAN
#define _WIN32_WINNT 0x0501
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iphlpapi.h>
#include <cstdio>
#define port 0x0ABC
UINT64 trStrLen (char* str)
{
    if (str == NULL) return 0;
    UINT64 pos = 0;
    while (*(str + pos) != '\0') pos++;
    return pos;
};
#include <cstdio>
int main ()
{
    WSADATA wsadata;
    if (WSAStartup(MAKEWORD(2,0),&wsadata)) return -1;
    SOCKET server = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    SOCKADDR_IN sin;
    memset(&sin,0,sizeof(SOCKADDR_IN));
    sin.sin_family = AF_INET;
    sin.sin_port = htons(port);
    sin.sin_addr.s_addr = INADDR_ANY;
    int socksize = sizeof(SOCKADDR);
    while (bind(server,(SOCKADDR*)(&sin),socksize) == SOCKET_ERROR) return -2;
    char* TEMP_TO_SEND = "Billy Mays does not approve.";
    UINT64 TEMP_SEND_LEN = trStrLen(TEMP_TO_SEND);
    printf("Server online.\n");
    while (true)
    {
        printf("Waiting for connections.\n");
        while (listen(server,SOMAXCONN) == SOCKET_ERROR);
        printf("Client requesting connection.\n");
        SOCKET client = accept(server,NULL,NULL);
        printf("Accept is no longer blocking.\n");
        if (client != INVALID_SOCKET)
        {
            printf("Attempting to send information to the client...\n");
            if (send(client,TEMP_TO_SEND,TEMP_SEND_LEN,0) == SOCKET_ERROR) printf("The information wasn't sent properly.\n");
            else printf("The client received the information.\n");
        }
        else printf("Couldn't establish a connection to the client.\n");
    };
};

Это, вероятно, что-то очевидное, но я не вижу его, поэтому любые советы помогут.

Теги:
winsock
listen

1 ответ

5
Лучший ответ

listen() не является блокирующим вызовом. Он ничего не делает с сетью. Он просто помещает сокет в режим пассивного прослушивания, устанавливает очередь на отставание и возвращается. Это accept() - это блокирующий вызов: он блокируется до тех пор, пока входящее соединение не будет завершено, а затем вернет для него сокет.

Таким образом, вы не должны называть listen() в while циклы на всех.

То же самое относится к bind(). Позвоните один раз.

  • 0
    Спасибо! Я думал, что слушатель ждал, когда будет какая-то связь, это очень помогает.
  • 0
    На самом деле я не знаю , почему в этом я поставил while петля для bind() . В моем реальном коде это было утверждение if . Делать какое- while здесь не имеет смысла.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню