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 Baglanti 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;
}
This question is related to
c
linux
sockets
tcp
file-descriptor
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.
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.
Source: Stackoverflow.com