Bad File Descriptor with Linux Socket write() Bad File Descriptor C
Solution 1
In general, when "Bad File Descriptor" is encountered, it means that the socket file descriptor you passed into the API is not valid, which has multiple possible reasons:
- The fd is already closed somewhere.
- The fd has a wrong value, which is inconsistent with the value obtained from socket() api
Solution 2
The value you have passed as the file descriptor is not valid. It is either negative or does not represent a currently open file or socket.
So you have either closed the socket before calling write()
or you have corrupted the value of 'sockfd' somewhere in your code.
It would be useful to trace all calls to close()
, and the value of 'sockfd' prior to the write()
calls.
Your technique of only printing error messages in debug mode seems to me complete madness, and in any case calling another function between a system call and perror()
is invalid, as it may disturb the value of errno
. Indeed it may have done so in this case, and the real underlying error may be different.
Solution 3
I had this error too, my problem was in some part of code I didn't close file descriptor and in other part, I tried to open that file!!
use close(fd)
system call after you finished working on a file.
user1336117
Updated on July 28, 2022Comments
-
user1336117 almost 2 years
I have an interesting problem with write(2) function. PrepareResponseForSetCoordinates function causes bad file descriptor error on write.
Here is the line of error: perror("ERROR writing to socket"); total output: ERROR writing to socket: Bad file descriptor
I am sure that I have established the connection because PrepareResponseForConnectionTest works like a charm.
Can you have any idea about the reason of the error?
When I use gcc as compiler there was no problem. After that because of using multiple new cpp sources I am using g++ as compiler and I have this error.
Regards
Here below my code:
#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);
}
Here below you can see the code which run without error:
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); }
Here is my InitializeConnection function and ConnectToServer function:
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; }
-
user207421 about 4 yearsThis problem is caused by prematurely closing it, not by not closing it.
-
Steven almost 3 yearsThanks for your analyze about possible reasons, those are helpful to find out where cause the bug.