Linux Socket写错文件描述符()坏文件描述符C

时间:2012-06-29 08:52:53

标签: c linux sockets tcp file-descriptor

我有一个写(2)函数的有趣问题。 PrepareResponseForSetCoordinates函数在写入时导致错误的文件描述符错误。

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

我确信我已经建立了连接,因为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 个答案:

答案 0 :(得分:13)

通常,当遇到“Bad File Descriptor”时,这意味着您传递给API的套接字文件描述符无效,这有多种可能的原因:

  1. fd已在某处关闭。
  2. fd的值不正确,这与从socket()api
  3. 获得的值不一致

答案 1 :(得分:5)

我也有这个错误,我的问题是代码的某些部分,我没有关闭文件描述符,而在其他方面,我试图打开该文件! 完成文件处理后使用close(fd)系统调用。

答案 2 :(得分:4)

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

所以你在调用write()之前关闭了套接字,或者你在代码中某处损坏了'sockfd'的值。

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

您只在调试模式下打印错误消息的技术在我看来完全疯了,无论如何在系统调用和perror()之间调用另一个函数是无效的,因为它可能会扰乱{{1}的值}。事实上,在这种情况下可能已经这样做了,真正的潜在错误可能会有所不同。