2012-06-29 138 views
1

写入(2)函数有一个有趣的问题。 PrepareResponseForSetCoordinates函数在写入时导致错误的文件描述符错误。使用Linux套接字写入错误文件描述符()错误文件描述符C

以下是错误行: perror(“ERROR writing to socket”); 总产量: 错误写入套接字:坏的文件描述符

我相信,我已经建立了连接,因为PrepareResponseForConnectionTest就像一个魅力。

你对这个错误的原因有什么想法吗?

当我使用gcc作为编译器时,没有问题。之后,因为使用多个新的cpp源,我使用g ++作为编译器,我有这个错误。

问候

这里我下面的代码:

#define MAX_PMS_MESSAGE_LEN (4096) 
unsigned char baCommBuffer[MAX_PMS_MESSAGE_LEN]; 
unsigned char PrepareResponseForSetCoordinates(void) 
{ 
    unsigned char baTempBuff[255]={0}; 
    unsigned short bCnt=0,i=0,bCsum=0,bCnt2=0; 
time_t lEpochTime; 
time_t lSessionTime; 

memset(baTempBuff,0,sizeof(baTempBuff)); 
memset(baCommBuffer,0,sizeof(baCommBuffer)); 
bzero(baCommBuffer,MAX_PMS_MESSAGE_LEN); 
bzero(baTempBuff,sizeof(baTempBuff)); 


lEpochTime = time(NULL); 
baCommBuffer[bCnt++] = START_CHAR; 
baCommBuffer[bCnt++] = START_CHAR; 
baCommBuffer[bCnt++] = PACKET_SEPERATOR; 
sprintf((char*)baTempBuff,"%ld",(unsigned long)lEpochTime); 
memcpy(baCommBuffer+bCnt,baTempBuff,10); 

bzero(baTempBuff,sizeof(baTempBuff)); 
bCnt+=10; 
baCommBuffer[bCnt++] = PACKET_SEPERATOR; 
// lSessionTime = time(NULL); 
if(SPMSMessage.lSessionID) 
lSessionTime = SPMSMessage.lSessionID; 
else 
lSessionTime=lEpochTime; 
sprintf((char*)baTempBuff,"%ld",(unsigned long)lSessionTime); 
memcpy(baCommBuffer+bCnt,baTempBuff,10); 
bzero(baTempBuff,sizeof(baTempBuff)); 
bCnt+=10; 
baCommBuffer[bCnt++] = PACKET_SEPERATOR; 
baCommBuffer[bCnt++] = PMC_ID; 
baCommBuffer[bCnt++] = PACKET_SEPERATOR; 
baCommBuffer[bCnt++] = PMS_ID; 
baCommBuffer[bCnt++] = PACKET_SEPERATOR; 
baCommBuffer[bCnt++] = 'R'; 
baCommBuffer[bCnt++] = 'E'; 
baCommBuffer[bCnt++] = 'P'; 
baCommBuffer[bCnt++] = PACKET_SEPERATOR; 
baCommBuffer[bCnt++] = 'C'; 
baCommBuffer[bCnt++] = 'O'; 
baCommBuffer[bCnt++] = 'O'; 
baCommBuffer[bCnt++] = 'S'; 
baCommBuffer[bCnt++] = PACKET_SEPERATOR; 
if(SPMSMessage.bParam== SET_COOR_CAM1_PARAM) 
{ 
baCommBuffer[bCnt++] = '2'; 
baCommBuffer[bCnt++] = PACKET_SEPERATOR; 
baCommBuffer[bCnt++] = 'O'; 
baCommBuffer[bCnt++] = 'N'; 
baCommBuffer[bCnt++] = 'E'; 
baCommBuffer[bCnt++] = PARAMETER_SEPERATOR; 
baCommBuffer[bCnt++] = 'A'; 
baCommBuffer[bCnt++] = 'C'; 
baCommBuffer[bCnt++] = 'K'; 
} 
else if(SPMSMessage.bParam== SET_COOR_CAM2_PARAM) 
{ 
baCommBuffer[bCnt++] = '2'; 
baCommBuffer[bCnt++] = PACKET_SEPERATOR; 
baCommBuffer[bCnt++] = 'T'; 
baCommBuffer[bCnt++] = 'W'; 
baCommBuffer[bCnt++] = 'O'; 
baCommBuffer[bCnt++] = PARAMETER_SEPERATOR; 
baCommBuffer[bCnt++] = 'A'; 
baCommBuffer[bCnt++] = 'C'; 
baCommBuffer[bCnt++] = 'K';  
} 
else 
{ 
baCommBuffer[bCnt++] = '1'; 
baCommBuffer[bCnt++] = PACKET_SEPERATOR; 
baCommBuffer[bCnt++] = 'N'; 
baCommBuffer[bCnt++] = 'A'; 
baCommBuffer[bCnt++] = 'C'; 
baCommBuffer[bCnt++] = 'K';   
} 
baCommBuffer[bCnt++] = PACKET_SEPERATOR; 
baCommBuffer[bCnt++] = '*'; 
memset(baTempBuff,0,sizeof(baTempBuff)); 
bCsum = CalculateCheckSum(baCommBuffer); 
sprintf((char*)baTempBuff,"%.2X",bCsum); 
memcpy(baCommBuffer+bCnt,baTempBuff,2); 
bzero(baTempBuff,sizeof(baTempBuff)); 
bCnt+=2; 
baCommBuffer[bCnt++] = PACKET_SEPERATOR; 
baCommBuffer[bCnt++] = END_CHAR; 
baCommBuffer[bCnt++] = END_CHAR; 

#ifdef _DEBUG_DEEP_DETAILED 
      if(EDebugDeepDetail<GetDebugLevelOfPMC()) 
      { 
        printf("WILL BE sent: %s uzunluk:%d\n", baCommBuffer,bCnt); 
        sprintf(caLogStr,"WILL BE sent: %s uzunluk:%d\n", baCommBuffer,bCnt); 
        PrintToLogFile(caLogStr); 
        memset(caLogStr,0,MAX_LOG_STRLEN); 
       } 
#endif 

     if((ETcpConnectionState== ETcpStateConnected) || (ETcpConnectionState== ETcpStateConnectedAndWaitingToWrite)) 
     { 

      if (write(sockfd,baCommBuffer,bCnt) < 0) 
      { 
       #ifdef _DEBUG_DETAILED 
       if(EDebugDetail<GetDebugLevelOfPMC()) 
       { 
        perror("ERROR writing to socket"); 
        PrintToLogFile("ERROR writing to socket"); 

       } 
       #endif 
      return 0; 
      } 
       #ifdef _DEBUG_DEEP_DETAILED 
       if(EDebugDeepDetail<GetDebugLevelOfPMC()) 
       { 
        printf("sent: %s uzunluk:%d\n", baCommBuffer,bCnt); 
        sprintf(caLogStr,"sent: %s uzunluk:%d\n", baCommBuffer,bCnt); 
        PrintToLogFile(caLogStr); 
        memset(caLogStr,0,MAX_LOG_STRLEN); 
       } 
       #endif 
     } 
     else 
     { 
       #ifdef _DEBUG_DETAILED 
        if(EDebugDetail<GetDebugLevelOfPMC()) 
        { 
        PrintToLogFile("Henüz Bağlantı Yok\n"); 
        } 
       #endif 
       return 0; 
     } 


return (bCnt); 

}

这里下面你可以看到其运行没有错误代码:

unsigned char PrepareResponseForConnectionTest(void) 
{ 

unsigned char baTempBuff[20]={0}; 
unsigned char bCnt=0,i=0,bCsum=0; 
time_t lEpochTime; 
time_t lSessionTime; 

memset(baTempBuff,0,sizeof(baTempBuff)); 
memset(baCommBuffer,0,sizeof(baCommBuffer)); 
bzero(baCommBuffer,MAX_PMS_MESSAGE_LEN); 
bzero(baTempBuff,sizeof(baTempBuff)); 


lEpochTime = time(NULL); 
baCommBuffer[bCnt++] = START_CHAR; 
baCommBuffer[bCnt++] = START_CHAR; 
baCommBuffer[bCnt++] = PACKET_SEPERATOR; 
sprintf((char*)baTempBuff,"%ld",(unsigned long)lEpochTime); 
memcpy(baCommBuffer+bCnt,baTempBuff,10); 

bzero(baTempBuff,sizeof(baTempBuff)); 
bCnt+=10; 
baCommBuffer[bCnt++] = PACKET_SEPERATOR; 

lSessionTime = SPMSMessage.lSessionID; 
sprintf((char*)baTempBuff,"%ld",(unsigned long)lSessionTime); 
memcpy(baCommBuffer+bCnt,baTempBuff,10); 
bzero(baTempBuff,sizeof(baTempBuff)); 
bCnt+=10; 
baCommBuffer[bCnt++] = PACKET_SEPERATOR; 
baCommBuffer[bCnt++] = PMC_ID; 
baCommBuffer[bCnt++] = PACKET_SEPERATOR; 
baCommBuffer[bCnt++] = PMS_ID; 
baCommBuffer[bCnt++] = PACKET_SEPERATOR; 
baCommBuffer[bCnt++] = 'R'; 
baCommBuffer[bCnt++] = 'E'; 
baCommBuffer[bCnt++] = 'P'; 
baCommBuffer[bCnt++] = PACKET_SEPERATOR; 
baCommBuffer[bCnt++] = 'C'; 
baCommBuffer[bCnt++] = 'O'; 
baCommBuffer[bCnt++] = 'N'; 
baCommBuffer[bCnt++] = 'T'; 
baCommBuffer[bCnt++] = PACKET_SEPERATOR; 
baCommBuffer[bCnt++] = '1'; 
baCommBuffer[bCnt++] = PACKET_SEPERATOR; 
baCommBuffer[bCnt++] = 'A'; 
baCommBuffer[bCnt++] = 'C'; 
baCommBuffer[bCnt++] = 'K'; 
baCommBuffer[bCnt++] = PACKET_SEPERATOR; 
baCommBuffer[bCnt++] = '*'; 
memset(baTempBuff,0,sizeof(baTempBuff)); 
bCsum = CalculateCheckSum(baCommBuffer); 
sprintf((char*)baTempBuff,"%.2X",bCsum); 
memcpy(baCommBuffer+bCnt,baTempBuff,2); 
bzero(baTempBuff,sizeof(baTempBuff)); 
bCnt+=2; 
baCommBuffer[bCnt++] = PACKET_SEPERATOR; 
baCommBuffer[bCnt++] = END_CHAR; 
baCommBuffer[bCnt++] = END_CHAR; 



     if((ETcpConnectionState== ETcpStateConnected) || (ETcpConnectionState== ETcpStateConnectedAndWaitingToWrite)) 
     { 

      if (write(sockfd,baCommBuffer,bCnt) < 0) 
      { 
      perror("ERROR writing to socket\n"); 
      PrintToLogFile("ERROR writing to socket\n"); 
      } 
       #ifdef _DEBUG_DEEP_DETAILED 
       if(EDebugDeepDetail<GetDebugLevelOfPMC()) 
       { 
        printf("sent: %s uzunluk:%d\n", baCommBuffer,bCnt); 
        sprintf(caLogStr,"sent: %s uzunluk:%d\n", baCommBuffer,bCnt); 
        PrintToLogFile(caLogStr); 
        memset(caLogStr,0,MAX_LOG_STRLEN); 
       } 
       #endif 
       return 0; 
     } 
     else 
     { 
       #ifdef _DEBUG_DETAILED 
        if(EDebugDetail<GetDebugLevelOfPMC()) 
        { 
        PrintToLogFile("There is no connection yet\n"); 
        } 
       #endif 
       //return 0; 
     } 

     //printf("\n\n"); 
return (bCnt); 
} 

这里是我的InitializeConnection功能和ConnectToServer功能:

void InitializeTcpConnection(int argc, char *argv[]) 
{ 
    int optval; 
    socklen_t optlen = sizeof(optval); 
ETcpConnectionState = ETcpStateNotConnected; 
    if (argc < 3) 
    { 
     fprintf(stderr,"usage: %s hostname_or_ip port\n", argv[0]); 
     #ifdef _DEBUG_PROCESS 
     if(EDebugProcess<GetDebugLevelOfPMC()) 
     { 
     sprintf(caLogStr,"usage: %s hostname_or_ip port\n", argv[0]); 
     PrintToLogFile(caLogStr); 
     memset(caLogStr,0,MAX_LOG_STRLEN); 
     } 
     #endif 
     exit(0); 
    } 
    portno = atoi(argv[2]); 
    /* int socket(domain,type,protocol) 
    * socket creates an endpoint for communication and returns a descriptor 
    * AF_INET: ARPA Internet protocols 
    * SOCK_STREAM: sequenced, two way connection based byte streams 
    * 
    * return: Socket returns a non-negative descriptor on success. 
    * On failure it returns -1 and sets errno to indicate the error 
    * */ 
    sockfd = socket(AF_INET, SOCK_STREAM, 0); 
    if (sockfd < 0) { 
     #ifdef _DEBUG_PROCESS 
     if(EDebugProcess<GetDebugLevelOfPMC()) 
     { 
     perror("ERROR creating socket"); 
     PrintToLogFile("ERROR creating socket\n"); 

     } 
     #endif 
     exit(1); 
    } 

    /**/ 


    /* Set the option active */ 
    optval = 1; 
    optlen = sizeof(optval); 
    if(setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen) < 0) 
    { 
     #ifdef _DEBUG_PROCESS 
     if(EDebugProcess<GetDebugLevelOfPMC()) 
     { 
      perror("setsockopt()"); 
      PrintToLogFile("ERROR creating socket\n"); 
     } 
     #endif 
     close(sockfd); 
     exit(EXIT_FAILURE); 
    } 
    #ifdef _DEBUG_PROCESS 
    if(EDebugProcess<GetDebugLevelOfPMC()) 
    { 
    printf("SO_KEEPALIVE set on socket\n"); 
    PrintToLogFile("SO_KEEPALIVE set on socket\n"); 
    } 
     #endif 
    /* Check the status again */ 
    if(getsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &optval, &optlen) < 0) { 
     #ifdef _DEBUG_PROCESS 
     if(EDebugProcess<GetDebugLevelOfPMC()) 
     { 
      perror("getsockopt()"); 
      PrintToLogFile("getsockopt()"); 
     } 
     #endif 
     close(sockfd); 
     exit(EXIT_FAILURE); 
    } 
    #ifdef _DEBUG_PROCESS 
    if(EDebugProcess<GetDebugLevelOfPMC()) 
    { 
    printf("SO_KEEPALIVE is %s\n", (optval ? "ON" : "OFF")); 
    } 
    #endif 

    #ifdef _DEBUG_PROCESS 

    if(EDebugProcess<GetDebugLevelOfPMC()) 
    { 
    PrintToLogFile("Setting socket for reusability\n"); 
    } 
    #endif 

    if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(int)) == -1) 
    { 
     #ifdef _DEBUG_PROCESS 
     if(EDebugProcess<GetDebugLevelOfPMC()) 
     { 
       perror("setsockopt"); 
       PrintToLogFile("Setting socket option error\n"); 
     } 
     #endif 
       exit(1); 
    } 

    /*********/ 

    //get the address info by either host name or IP address 
    SetTcpServerIpAddress(argv[1]); 
    server = gethostbyname(argv[1]); 
    if (server == NULL) 
    { 
     #ifdef _DEBUG_PROCESS 
     if(EDebugProcess<GetDebugLevelOfPMC()) 
     { 
     PrintToLogFile("ERROR, no such host\n"); 
     } 
     #endif 
     exit(1); 
    } 

    bzero((char *) &serv_addr, sizeof(serv_addr)); 
    serv_addr.sin_family = AF_INET; 
    bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length); 
    //serv_addr.sin_port: unsigned short 
    //htons converts the unsigned short hostshort from host byte order to network byte order 
    serv_addr.sin_port = htons(portno); 


    ETcpConnectionState = ETcpStateWaitingForConnection; 

} 

int ConnectToServer(void) 
{ 
        if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) 
        { 
         #ifdef _DEBUG_DETAILED 
         if(EDebugDetail<GetDebugLevelOfPMC()) 
         { 
         PrintToLogFile("ERROR connecting"); 
         } 
         #endif 
         return 1; // connection error 
         //exit(1); 
        } 
        else 
        { 
         #ifdef _DEBUG_DETAILED 
         if(EDebugDetail<GetDebugLevelOfPMC()) 
         { 
         PrintToLogFile("connection established\n"); 
         } 
         #endif 
        #ifndef PMS_COMM_POLL_MODE 
         #ifdef _DEBUG_DETAILED 
         if(EDebugDetail<GetDebugLevelOfPMC()) 
         { 
         PrintToLogFile("State is non poll mode\n"); 
         } 
         #endif 
        ETcpConnectionState = ETcpStateConnected; 
        #endif 
        #ifdef PMS_COMM_POLL_MODE 
         #ifdef _DEBUG_DETAILED 
         if(EDebugDetail<GetDebugLevelOfPMC()) 
         { 
         PrintToLogFile("State is poll mode\n"); 
         } 
         #endif 
        ETcpConnectionState = ETcpStateConnectedAndWaitingToRead; 
        #endif 

        SendRequestToGetImageUploadInfo(); 
        } 
return 0; 
} 
+3

很多不相关的代码。什么是'sockfd'?它在哪里宣布?它是如何初始化的?你如何通过它?你是否在'sockfd'的某个地方使用了'='而不是'=='? –

+0

我添加了初始化源。定义: int sockfd,portno; struct sockaddr_in serv_addr; – user1336117

回答

7

在一般情况下,当遇到“错误的文件描述符”,这意味着你传递到API的套接字文件描述符是无效的,它有多种可能的原因:

  1. 的FD已经某处关闭。
  2. 的FD有一个错误的值,这与从插座()API
3

您作为文件描述符传递的值无效。它是否定的,或者不代表当前打开的文件或套接字。

因此,您在调用write()之前关闭了套接字,或者在代码中某处损坏了“sockfd”的值。

在write()调用之前跟踪所有调用close()以及'sockfd'的值会很有用。

只有在调试模式下打印错误消息的技术似乎对我来说完全是疯狂的,并且在任何情况下调用系统调用和perror()之间的另一个函数都是无效的,因为它可能会干扰errno的值。事实上,在这种情况下它可能会这样做,而真正的潜在错误可能会有所不同。

5

我也有这种错误所得到的值不一致,我的问题是在代码中的一些部分我没有关闭文件描述符在其他部分,我试图打开该文件! 在完成文件处理后使用close(fd)系统调用。

相关问题