2

我有代码(我的 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;
}

再次感谢。

4

2 回答 2

3

您必须为此使用循环:)

基本上,服务器主代码必须处于一个循环中,这将永远持续下去......而你不停止它。

你应该有 :

// That's close to pseudo code :)

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

// close the listen socket here

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

my2c

于 2011-01-26T10:51:52.857 回答
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() 分配。然后让客户端套接字在自己的线程上运行。

此外,由于某种原因,您正在代码中间关闭您的监听套接字。

于 2011-01-26T11:01:25.163 回答