Как я всегда могу открыть сервер? - PullRequest
2 голосов
/ 26 января 2011

У меня есть код (мой сервер сокетов c ++), но я не знаю, как мне всегда открывать.Мой сервер закроется.когда оно уже отправлено клиенту, оно само закроется.Но я хочу, чтобы он дождался других клиентов и никогда не закрывался.Как мне это сделать ?О, я тоже использую многопоточность.

пожалуйста, помогите мне.

и вот мой код

int main(void)
{
  HANDLE hThread[3];
  DWORD dwID[3];
  DWORD dwRetVal = 0;

  hThread[0] = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadTwo,NULL,0,&dwID[0]);

  dwRetVal = WaitForMultipleObjects(3, hThread, TRUE, INFINITE);

  CloseHandle(hThread[0]);

 return 0;
}

long WINAPI ThreadTwo(long lParam)
{
  WSADATA wsaData;
    SOCKET ListenSocket = INVALID_SOCKET,
           ClientSocket = INVALID_SOCKET;
    struct addrinfo *result = NULL,
                    hints;
    char recvbuf[DEFAULT_BUFLEN];
    int iResult, iSendResult;
    int recvbuflen = DEFAULT_BUFLEN;

    iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
    if (iResult != 0) {
        printf("WSAStartup failed with error: %d\n", iResult);
        return 1;
    }

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

    iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
    if ( iResult != 0 ) {
        printf("getaddrinfo failed with error: %d\n", iResult);
        WSACleanup();
        return 1;
    }

    ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
    if (ListenSocket == INVALID_SOCKET) {
        printf("socket failed with error: %ld\n", WSAGetLastError());
        freeaddrinfo(result);
        WSACleanup();
        return 1;
    }

    iResult = bind( ListenSocket, result->ai_addr, (int)result->ai_addrlen);
    if (iResult == SOCKET_ERROR) {
        printf("bind failed with error: %d\n", WSAGetLastError());
        freeaddrinfo(result);
        closesocket(ListenSocket);
        WSACleanup();
        return 1;
    }

    freeaddrinfo(result);

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

    printf("Waiting for client\n");

    ClientSocket = accept(ListenSocket, NULL, NULL);
    if (ClientSocket == INVALID_SOCKET) {
        printf("accept failed with error: %d\n", WSAGetLastError());
        closesocket(ListenSocket);
        WSACleanup();
        return 1;
    }

    printf("Client acctped.\n");

    closesocket(ListenSocket);

    do {

        iResult = recv(ClientSocket, recvbuf, recvbuflen, 0);
        if (iResult > 0) {
            printf("Bytes received: %d\n", iResult);

            recvbuf[iResult] = '\0';
            printf(recvbuf);

            char* testsend = "222 333\n444 555\n666 777" ;

            iSendResult = send( ClientSocket, testsend , strlen(testsend)+1 , 0 );
            if (iSendResult == SOCKET_ERROR) {
                printf("send failed with error: %d\n", WSAGetLastError());
                closesocket(ClientSocket);
                WSACleanup();
                return 1;
            }
            printf("Bytes sent: %d\n", iSendResult);
        }
        else if (iResult == 0)
            printf("Connection closing...\n");
        else  {
            printf("recv failed with error: %d\n", WSAGetLastError());
            closesocket(ClientSocket);
            WSACleanup();
            return 1;
        }

    } while (iResult > 0);

    iResult = shutdown(ClientSocket, SD_SEND);
    if (iResult == SOCKET_ERROR) {
        printf("shutdown failed with error: %d\n", WSAGetLastError());
        closesocket(ClientSocket);
        WSACleanup();
        return 1;
    }
    system("pause");

    closesocket(ClientSocket);
    WSACleanup();

  return 0;
}

спасибо еще раз.

Ответы [ 2 ]

3 голосов
/ 26 января 2011

Вы должны использовать цикл для этого:)

По сути, основной код сервера должен быть в цикле, который будет работать вечно ... пока вы его не остановите.

вы должны иметь:

// That's close to pseudo code :)

while(notStoppedByMaster)
{
    // [...]
    ClientSocket = accept(ListenSocket, NULL, NULL);
    handleRequest(ClientSocket);
}

// close the listen socket here

handleRequest должен обрабатывать запрос в другом потоке . Будьте внимательны к синхронизации :)

my2c

0 голосов
/ 26 января 2011

Во-первых, похоже, что вы создаете консольное приложение.На вашем месте я бы создал приложение WIN32.Это означает, что у вас будет графический интерфейс, но что более важно, цикл сообщений.Цикл сообщений позволяет использовать асинхронные сокеты, требует немного больше понимания, но дает гораздо лучшие и более чистые результаты.

Прочитайте о WSAAsyncSelect: http://msdn.microsoft.com/en-us/library/ms741540%28VS.85%29.aspx Также прочитайте учебник по сокетам: http://msdn.microsoft.com/en-us/library/ms738545%28v=VS.85%29.aspx

Во-вторых, если вы ДОЛЖНЫ использовать синхронные (блокирующие) сокеты, да, вам придется запускать каждый из них в отдельном потоке.Вам нужно иметь цикл, в котором вы ожидаете соединения, а затем иметь клиентские сокеты, как вы сделали, назначенные из вашего accept ().Затем позвольте клиентским сокетам работать в своем собственном потоке.

Кроме того, по какой-то причине вы закрываете свой listensocket в середине кода.

...