我对 write(2) 函数有一个有趣的问题。PrepareResponseForSetCoordinates 函数会导致写入时出现错误的文件描述符错误。
这是错误行: 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;
}