3

私はこのウェブサイトを初めて使用するので、ここで全員に公開する前に検索しましたが、この質問が以前に回答されている場合は、事前に謝罪します.

C プログラムの 1 つでソケット プログラミングを使用しています。サーバーとクライアントが双方向で通信できるサーバーとクライアントのモジュールがあります。ファイルとメッセージを双方向に送信できるため、プログラムは正常に動作しています。私のサーバープログラムはポート3873を使用しており、これを確認しましたnetstat -anp | grep 3873

http://localhost:3873特にやなどのブラウザを使用してソケットに接続しようとすると、ソケットで奇妙な動作が 1 つ見られますtelnet localhost 3873。すぐにソケットを閉じ、その後の 'netstat -anp | grep 3873 の出力は、localhost がポートでリッスンしていないことを確認します3873

誰かがこの行動に光を当てることができれば、本当に感謝しています。期待される動作ですか?

サーバーコードの関連セクションは次のとおりです。メインプログラムは専用スレッドを開始し、startFileServerMT を呼び出します。その後、handleClient を呼び出して、ソケット上のサーバーに接続された各クライアントにサービスを提供します。

int handleClient(void *ptr){
    DEBUG("Inside the %s %s() \n",__FILE__,__func__);
    int  connectSOCKET;
    connectSOCKET = (int ) ptr;
    char recvBUFF[4096],sendBUFF[4096];
    char *filename;
    FILE * recvFILE;
    char *header[4096];    
    while(1){
        if( recv(connectSOCKET, recvBUFF, sizeof(recvBUFF), 0) > 0){
            if(!strncmp(recvBUFF,"FBEGIN",6)) {                          
                recvBUFF[strlen(recvBUFF) - 2] = 0;
                parseArgs(header,recvBUFF);                                 
                filename = (char*) strngDup(header[1]);                                
                DEBUG("  About to receive file: %s\n", filename);
            }

            char *rfile = ALLOC(sizeof(char) * (strlen(This.uploadDIR) + strlen(filename) + 35));
            strcpy(rfile,This.uploadDIR);

            if (strngLastChar(rfile) == '/'){
                strcat(rfile,filename);
            }else{
                strcat(rfile,"/");
                strcat(rfile,filename);        
            }
            DEBUG("  Absolute file is : %s\n", rfile);
            recvBUFF[0] = 0;
            if ((recvFILE = fopen (rfile,"w" )) == NULL){
                LogError("Server could not create file %s on the shared location %s.\n",filename,This.uploadDIR);                
            }else{
                bzero(recvBUFF,4096);
                int fr_block_sz, write_sz;
                while((fr_block_sz = recv(connectSOCKET, recvBUFF, 512, 0)) > 0 ){
                    write_sz = fwrite (recvBUFF , sizeof(recvBUFF[0]) , fr_block_sz , recvFILE );
                    DEBUG("  Received buffer is : %s\n", recvBUFF);
                    if(write_sz < fr_block_sz){
                        LogError("Failed writing file %s on the Server shared location.\n",filename);
                        break;
                    }
                    bzero(recvBUFF,4096);
                    recvBUFF[0] = 0;
                    if(write_sz == 0 || fr_block_sz != 512 ){   
                        break;
                    }
                }

                if(fr_block_sz < 0){
                    if(errno == EAGAIN){
                        LogError("Server collection file %s receive timed out.\n",filename);
                    }else{
                        LogError("Failed file %s transfer due to error %d\n",filename,errno);
                        fclose(recvFILE);
                        FREE(rfile);
                        // Start - Following code send failed status to client    
                        sprintf(sendBUFF,"FSTATUS:FAILED\r\n");    

                        if (send(connectSOCKET, sendBUFF, sizeof(sendBUFF), 0) >= 0){
                            DEBUG("File transfer status for file %s sent\n",filename);
                        }else{
                            DEBUG("Failed sending transfer status for file %s\n",filename);
                            return FALSE;
                        } 

                        // End

                        close(connectSOCKET);
                        return FALSE;
                    }
                }
                    DEBUG("File %s received on OM Server successfully.\n",filename);

                    // Start - Following code send failed status to client    
                    sprintf(sendBUFF,"FSTATUS:SUCCESS\r\n");    

                    if (send(connectSOCKET, sendBUFF, sizeof(sendBUFF), 0) >= 0){
                        DEBUG("File transfer status for file %s sent\n",filename);
                    }else{
                        DEBUG("Failed sending transfer status for file %s\n",filename);
                        return FALSE;
                    } 
                    // End

                    fclose(recvFILE);
                    updateTargets(rfile);
                    FREE(rfile);
                    close(connectSOCKET);
                    break;

            }
        }
        else {
            LogInfo("Client dropped connection\n");
        }

/** End*/  
        return TRUE;
    }    
}

int startFileServerMT(){
    DEBUG("Inside %s %s() \n",__FILE__,__func__);

    int listenSOCKET, connectSOCKET[512],thread_status;
    int socketINDEX = 0;

    pthread_t clientFileThread[512];
    socklen_t clientADDRESSLENGTH[512];
    struct sockaddr_in clientADDRESS[512], serverADDRESS;    


    if((listenSOCKET = socket(AF_INET, SOCK_STREAM, 0)) < 0 ){
        LogAbortError("File server could not create socket.\n");
        close(listenSOCKET);
        return FALSE;        
    }

    serverADDRESS.sin_family = AF_INET;
    serverADDRESS.sin_addr.s_addr = htonl(INADDR_ANY);  
    serverADDRESS.sin_port = htons(This.serverport);

    if (bind(listenSOCKET, (struct sockaddr *) &serverADDRESS, sizeof(serverADDRESS)) < 0) {
        LogAbortError("File server could not bind socket and will stop server now.\n");
        close(listenSOCKET);
        This.stopped = TRUE;
        return FALSE;
    }

    if(listen(listenSOCKET, 5) == -1){
        LogAbortError("Server failed to listen on port %d and will stop server now.\n",This.serverport);
        close(listenSOCKET);
        This.stopped = TRUE;
        return FALSE;        
    }else{
        LogInfo("Server listening on port %d successfully.\n",This.serverport);        
    }

    clientADDRESSLENGTH[socketINDEX] = sizeof(clientADDRESS[socketINDEX]);

    while(TRUE){   
       // DEBUG("  Inside the file server main loop index[%d].\n",socketINDEX);

        connectSOCKET[socketINDEX] = accept(listenSOCKET, (struct sockaddr *) &clientADDRESS[socketINDEX], &clientADDRESSLENGTH[socketINDEX]);
            if(connectSOCKET[socketINDEX] < 0){
            LogError("Server could not accept connection.\n");
            close(listenSOCKET);
            return FALSE;
        }else
            DEBUG("  Another client connected to server socket.\n");

        ThreadCreateDetached( &clientFileThread[socketINDEX], handleClient, connectSOCKET[socketINDEX]);     

        if(socketINDEX=512) {
            socketINDEX = 0;
        } else { 
            socketINDEX++;
        }                                  

        if (This.stopped == TRUE){
            close(listenSOCKET);
            return TRUE;
        }      
/** End*/  
//        return TRUE;
    }

    close(listenSOCKET);
    return TRUE;

}
4

1 に答える 1

0

これはあなたの問題です - または少なくともあなたの問題の一部です。これは、off-by-one エラーであるだけでなく (connectSOCKET は 0 から 511 までのインデックスを受け入れるため、512 にいる場合は、connectSOCKET 配列の末尾を超えて既に書き込み済みです)、比較ではなく代入を行います。

    if(socketINDEX=512) { // Error: you are *setting* socketINDEX to 512, 
                          // then immediately *resetting* it back to 0. So
                          // every new connection overrides the existing
                          // socket.
        socketINDEX = 0;
    } else { 
        socketINDEX++;
    }

補足として、コードをリファクタリングしてクリーンアップを試みる必要があります。

于 2013-01-21T22:59:27.243 に答える