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()から割り当てられたのと同じようにクライアントソケットを作成する必要があります。次に、クライアントソケットを独自のスレッドで実行します。

また、コードの途中で何らかの理由でlistensocketを閉じています。

于 2011-01-26T11:01:25.163 に答える