我怎么能一直打开服务器?

时间:2011-01-26 10:34:52

标签: c++ sockets serversocket

我有代码(我的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 个答案:

答案 0 :(得分:3)

你必须使用循环:)

基本上,服务器主代码必须处于循环中,这将永远存在...而你不会停止它。

你应该:

// That's close to pseudo code :)

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

// close the listen socket here

handleRequest应该在另一个线程中处理请求注意同步:)

MY2C

答案 1 :(得分:0)

首先,看起来您正在创建一个控制台应用程序。如果我是你,我会创建一个WIN32应用程序。这意味着你将拥有一个GUI,但更重要的是一个消息循环。消息循环允许您使用异步套接字,它需要更多的理解,但它提供了更好,更清晰的结果。

阅读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()中分配。然后让客户端套接字在自己的线程上运行。

此外,您在代码中间因某种原因关闭了侦听器。