1

while(1) ループがあるコードを書いています。while(1) ループ内には、メッセージ ボックスと recvfrom() 関数があり、私の理解によれば、データが受信されるか recvfrom() 関数が失敗するまで、recvfrom() の呼び出しでブロックする必要があります。

しかし、実際には、while(1) ループが継続してメッセージ ボックスを表示し続け、recvfrom() ステートメントに移動しません。

問題があると思われる部分を強調表示しました。

つまり、while(1) は最初のステートメントでスタックしています。支援のためにコード全体を追加しています。私の間違いを理解するのを手伝ってください。

DWORD WINAPI sendThreadProcedure(LPVOID param)
{
    int PORT = 9999;
    WSADATA wsa; 

    //Initialise winsock//
    if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
    {
        exit(EXIT_FAILURE);
    } 

    //Create a socket//   
    SOCKET sendSocketIdentifier;
    SOCKADDR_IN sendSocket;  
    if((sendSocketIdentifier = socket(AF_INET , SOCK_DGRAM , 0 )) == INVALID_SOCKET)
    {
        exit(EXIT_FAILURE);
    }
    //Socket Created//

    //Prepare the sockaddr_in structure//
    sendSocket.sin_family = AF_INET;
    sendSocket.sin_addr.s_addr = INADDR_ANY;
    sendSocket.sin_port = htons(PORT);

    //Bind//
    if( bind(sendSocketIdentifier ,(struct sockaddr *)&sendSocket, sizeof(SOCKADDR_IN)) == SOCKET_ERROR)
    {
        // "BIND FAILED",
        exit(EXIT_FAILURE);
    }

    int clientSocketLength = sizeof(SOCKADDR_IN);
    char receiveBuffer[10000];
    int recv_len=0;
    //=======================================================================

    char threadNumberBuffer[256] = "Thread Number : ";
    char buff[32];
    char file[32]="Master";
    char fileName[128];
    int sendCount=0;
    FILE *fpSend;
    itoa(threadNumber,buff,10);
    strcat(threadNumberBuffer,buff);

    strcpy(fileName,file);
    strcat(fileName,buff);
    strcat(fileName,".txt");
    MSG msg;

    // Start of problem area
    while(1)
    {
        MessageBox( NULL,
                    "Going in while loop",
                    "", 
                    MB_ICONINFORMATION);     

        recv_len = recvfrom(sendSocketIdentifier, receiveBuffer, 
                            sizeof(receiveBuffer), 0,
                            (struct sockaddr *) &clientSocket,
                            &clientSocketLength)
        {
            // "Could not receive data at start of sending thread"
        }
        // End of problem area

        //"Start of Receive thread"

        while(GetMessage(&msg, NULL, 0, 0) > 0)
        {
            if(msg.message == Send_File)
            {
                if((fpSend = fopen(TEXT(fileName), "r+b")) == NULL)
                {
                    MessageBox( NULL,
                                "Unable to open the File",
                                "Error!",
                                MB_ICONEXCLAMATION | 
                                MB_OK);
                }

                char file_buffer[10000];
                int bytes_read=0;
                char new_buffer[1000] = "FILE",send[1000];
                if(sendto(sendSocketIdentifier, new_buffer, sizeof(new_buffer), 0,
                          (struct sockaddr *) &clientSocket, 
                          sizeof(clientSocket)) < 0)
                {
                    MessageBox( NULL,
                                "NOT SENNT!",
                                "ERROR!",
                                MB_ICONEXCLAMATION | 
                                MB_OK);
                    break;
                }
                while(fpSend!=NULL)
                {
                    if((bytes_read=fread(file_buffer, sizeof(char), 1, fpSend))<=0)
                    {
                        if(feof(fpSend))
                        {
                            char new_buffer[1000] = "EXIT",send[1000];
                            if(sendto(sendSocketIdentifier, new_buffer, 
                                      sizeof(new_buffer), 0, 
                                      (struct sockaddr *) &clientSocket, 
                                      sizeof(clientSocket)) < 0)
                            {
                                MessageBox( NULL,
                                            "NOT SENNT!",
                                            "ERROR!",
                                            MB_ICONEXCLAMATION | 
                                            MB_OK);
                                break;
                            }
                            char send_Count[128];

                            itoa(sendCount,send_Count,10);
                            fclose(fpSend);
                            break;
                            return 0;
                        }
                        else
                        {
                            char err[128], bread[128];

                            itoa(errno,err,10);
                            itoa(bytes_read,bread,10);
                            MessageBox( NULL,
                                        "Unable to copy file into buffer",
                                        bread,
                                        MB_ICONEXCLAMATION | 
                                        MB_OK);
                            fclose(fpSend);
                            break;
                        }
                    }
                    else
                    {
                        if(sendto(sendSocketIdentifier, file_buffer, 
                                  bytes_read, 0, 
                                  (struct sockaddr *) &clientSocket,
                                  sizeof(clientSocket)) < 0)
                        {
                            MessageBox( NULL,
                                        "NOT SENNT!",
                                        "ERROR!",
                                        MB_ICONEXCLAMATION | 
                                        MB_OK);
                            break;
                        }
                        else
                        {
                            sendCount = sendCount+1;
                        }
                    }
                }
                //======================Sent a File at Socket===========================
            }
            else
                DispatchMessage(&msg);
        }
    }
    return 0;
}

編集: コードを次のように切り捨てても、それでもメッセージボックスが40回近く表示され、その後recvfrom()が呼び出される可能性があります。

while(1)
{
    MessageBox( NULL,
                "Going in while loop",
                "", 
                MB_ICONINFORMATION);
    if((recv_len = recvfrom(sendSocketIdentifier, receiveBuffer, 
                            sizeof(receiveBuffer), 0, 
                            (struct sockaddr *) &clientSocket, 
                            &clientSocketLength)) == SOCKET_ERROR)
    {
        char err[128];
        itoa(WSAGetLastError(),err,10);
        MessageBox( NULL,
                    "Could not receive data at start of sending thread",
                    err, 
                    MB_ICONINFORMATION);
    }

    MessageBox( NULL,
                receiveBuffer,
                "Start of Receive thread", 
                MB_ICONINFORMATION);
}
4

1 に答える 1

2

メッセージボックスが継続的に表示されている場合は、条件が満たされているため receive が返されます。

  1. ソケットに問題があり、受信が -1 を返します
  2. すでに利用可能なデータがあり、それを読む必要があります。返品を受け取る > 0
  3. あなたのソケットはノンブロッキングです == -1
  4. ソケットがタイムアウトしました == 0 (この場合ではありません)

だからあなたがしなければならないことは、受信からの戻り値をチェックして、それが何を言っているかを見ることです. -1 の場合は、さらに errno を調べて、何を伝えようとしているのかを調べます。

于 2013-05-20T07:35:00.917 に答える