#include<setjmp.h>
#include<signal.h>
jmp_buf read_msg_timeout;
int main( void )
{
int iRet = 0;
iRet = setjmp( read_msg_timeout );
printf("aa:iRet=[%d]\n", iRet);
longjmp(read_msg_timeout, 5);
return 0;
}
运行结果:
aa:iRet=[0]
aa:iRet=[5]
aa:iRet=[5]
aa:iRet=[5]
实际用途:
jmp_buf read_msg_timeout;
void ReadMsgTimeout( int iSig )
{
signal( iSig, SIG_IGN );
longjmp( read_msg_timeout, 1 );
}
int RecvMsgFromSocket( int communfd, char *pczTranBuf,
int *piBuflen, int iDelayTime, int iHeadFlag )
{
int iLen, iAll, iLeft, iRead;
int iHeadLen;
int i;
char cLRC;
/* save the head of the transaction and the transaction */
char pczTmpBuf[ MAX_DATA_LEN ];
char pczTmpBuf1[ MAX_DATA_LEN ];
char pczTmp[ 20 ];
char *ptr;
/*
** clear the work area
*/
memset( pczTmpBuf, 0x00, sizeof( pczTmpBuf ) );
memset( pczTmpBuf1, 0x00, sizeof( pczTmpBuf1 ) );
memset( pczTmp, 0x00, sizeof( pczTmp ) );
if( iDelayTime < 0 )
{
return( -1101 );
}
if( iHeadFlag < 0 || iHeadFlag > 13 )
{
return( -1102 );
}
/*
** use the alarm to control the socket read
*/
signal( SIGALRM, ReadMsgTimeout );
/***********
若超时,则会执行ReadMsgTimeout 函数,而ReadMsgTimeout 函数会调用 longjmp( read_msg_timeout, 1 ),使得setjmp( read_msg_timeout ) =1,
因此超时则会执行else里面的return( -1100 )
***********/
if( setjmp( read_msg_timeout ) == 0 )
{
alarm( iDelayTime );
/*
** 测试第一次读入的长度
*/
if( iHeadFlag == NO_HEAD )
{
iHeadLen = MAX_DATA_LEN;
}
else if( iHeadFlag == HEXBYTE_TWO_HAS_HEAD )
{
iHeadLen = 2;
}
else if( iHeadFlag == HEXBYTE_TWO_NONE_HEAD )
{
iHeadLen = 2;
}
else if( iHeadFlag == ASCII_FOUR_HAS_HEAD )
{
iHeadLen = 4;
}
else if( iHeadFlag == ASCII_FOUR_NONE_HEAD )
{
iHeadLen = 4;
}
else if( iHeadFlag == ASCII_EIGHT_NONE_HEAD )
{
iHeadLen = 8;
}
else if( iHeadFlag == THREE_SYNC_HEXBYTE_TWO_NONE_HEAD )
{
iHeadLen = 5;
}
else if( iHeadFlag == ASCII_NINETY_NO_HEAD )
{
iHeadLen = 90;
}
else if( iHeadFlag == TWO_SYNC_NETSHORT_NONE_HEAD )
{
iHeadLen = 4;
}
else if (iHeadFlag == SYNC_ASCII_FOUR_NONE_HEAD_SYNC_LRC)
{
iHeadLen = 5;
}
else if (iHeadFlag == NETLONG_NONE_HEAD)
{
iHeadLen = sizeof (long);
}
else if (iHeadFlag == NETSHORT_NONE_HEAD)
{
iHeadLen = sizeof (short);
}
else if (iHeadFlag == NETLONG_HAS_HEAD)
{
iHeadLen = sizeof (long);
}
else if (iHeadFlag == NETSHORT_HAS_HEAD)
{
iHeadLen = sizeof (short);
}
/*
** read the head, check the head,
** and obtain the length of the transaction
*/
if( ( iLen = u_read( communfd, pczTmpBuf, iHeadLen ) ) < 0 )
{
alarm( 0 );
return ( -1104 );
}
/*
** 处理长度头
*/
if( iHeadFlag == NO_HEAD )
{
memcpy( pczTranBuf, pczTmpBuf, iLen );
*piBuflen = iLen;
alarm( 0 );
return( iLen );
}
else if( iHeadFlag == HEXBYTE_TWO_HAS_HEAD )
{
if( iLen != 2 )
{
alarm( 0 );
return( -1105 );
}
/*
** check the head are right
** and change it to int
*/
iAll = ( unsigned char )pczTmpBuf[ 0 ] * 256 + ( unsigned char )pczTmpBuf[ 1 ] - 2;
*piBuflen = iAll;
}
else if( iHeadFlag == HEXBYTE_TWO_NONE_HEAD )
{
if( iLen != 2 )
{
alarm( 0 );
return( -1106 );
}
/*
** check the head are right
** and change it to int
*/
iAll = ( unsigned char )pczTmpBuf[ 0 ] * 256 + ( unsigned char ) pczTmpBuf[ 1 ];
*piBuflen = iAll;
}
else if( iHeadFlag == ASCII_FOUR_HAS_HEAD )
{
if( iLen != 4 )
{
alarm( 0 );
return( -1107 );
}
/*
** check the head are all digit
** and change it to int
*/
if( IsDigit( pczTmpBuf ) )
{
alarm( 0 );
return( -1108 );
}
else
{
iAll = atoi( pczTmpBuf ) - 4;
*piBuflen = iAll;
}
}
else if( iHeadFlag == ASCII_NINETY_NO_HEAD )
{
if( iLen != 90 )
{
alarm( 0 );
return( -1109 );
}
/*
** check the head are all digit
** and change it to int
*/
memcpy(pczTmp,pczTmpBuf + 85 , 5);
if( IsDigit( pczTmp ) )
{
alarm( 0 );
return( -1110 );
}
else
{
iAll = atoi( pczTmp );
*piBuflen = iAll + 85 ;
memcpy(pczTmpBuf1,pczTmpBuf,85);
}
}
else if( iHeadFlag == ASCII_FOUR_NONE_HEAD )
{
if( iLen != 4 )
{
alarm( 0 );
return( -1109 );
}
/*
** check the head are all digit
** and change it to int
*/
if( IsDigit( pczTmpBuf ) )
{
alarm( 0 );
return( -1110 );
}
else
{
iAll = atoi( pczTmpBuf );
*piBuflen = iAll;
}
}
else if( iHeadFlag == ASCII_EIGHT_NONE_HEAD )
{
if( iLen != 8 )
{
alarm( 0 );
return( -1109 );
}
/*
** check the head are all digit
** and change it to int
*/
if( IsDigit( pczTmpBuf ) )
{
alarm( 0 );
return( -1110 );
}
else
{
iAll = atoi( pczTmpBuf );
*piBuflen = iAll;
if( iAll > 32768 )
{
alarm( 0 );
return( -1312 );
}
}
}
else if( iHeadFlag == THREE_SYNC_HEXBYTE_TWO_NONE_HEAD )
{
if( iLen != 5 )
{
alarm( 0 );
return( -1111 );
}
if( memcpy( pczTmpBuf, "\002\0\0", 3 ) != 0 )
{
alarm( 0 );
return( -1112 );
}
/*
** check the head are right
** and change it to int
*/
iAll = ( unsigned char )pczTmpBuf[ 3 ] * 256 +
( unsigned char ) pczTmpBuf[ 4 ];
*piBuflen = iAll;
}
else if (iHeadFlag == SYNC_ASCII_FOUR_NONE_HEAD_SYNC_LRC)
{
if (iLen != 5) {
alarm (0);
return (-1114);
}
if (pczTmpBuf[0] != 0x02) {
alarm( 0 );
return( -1115 );
}
cLRC = 0;
for (i = 0; i< iLen; i++) {
cLRC = cLRC ^ pczTmpBuf[i];
}
if (IsDigit (pczTmpBuf + 1)) {
alarm( 0 );
return( -1118 );
} else {
iAll = atoi (pczTmpBuf + 1);
*piBuflen = iAll;
}
}
else if( iHeadFlag == NETLONG_NONE_HEAD )
{
if( iLen != sizeof (long) )
{
alarm( 0 );
return( -1109 );
}
memcpy(pczTranBuf,pczTmpBuf,iLen);
iAll = ntohl (*((long *)pczTmpBuf));
*piBuflen = iAll;
}
else if( iHeadFlag == NETSHORT_NONE_HEAD )
{
if( iLen != sizeof (short) )
{
alarm( 0 );
return( -1109 );
}
memcpy(pczTranBuf,pczTmpBuf,iLen);
iAll = ntohs (*((short *)pczTmpBuf));
*piBuflen = iAll;
}
else if( iHeadFlag == NETLONG_HAS_HEAD )
{
if( iLen != sizeof (long) )
{
alarm( 0 );
return( -1109 );
}
iAll = ntohl (*((long *)pczTmpBuf)) - sizeof (long);
*piBuflen = iAll;
}
else if( iHeadFlag == NETSHORT_HAS_HEAD )
{
if( iLen != sizeof (short) )
{
alarm( 0 );
return( -1109 );
}
iAll = ntohs (*((short *)pczTmpBuf)) - sizeof (short);
*piBuflen = iAll;
}
else if( iHeadFlag == TWO_SYNC_NETSHORT_NONE_HEAD )
{
if( iLen != 4 )
{
alarm( 0 );
return( -1111 );
}
if( memcmp( pczTmpBuf, "\x03\x00", 2 ) != 0 )
{
alarm( 0 );
return( -1112 );
}
/*
** check the head are right
** and change it to int
*/
iAll = ntohs( *( unsigned short * )( pczTmpBuf + 2 ) );
*piBuflen = iAll;
}
/*
** read the socket, obtain the transaction
** if the read_length is not equal to transaction_length
** read the socket again
*/
iLeft = iAll; /* save the end of the transaction */
ptr = pczTranBuf; /* save the transaction */
if (iHeadFlag == ASCII_NINETY_NO_HEAD)
{
memcpy( ptr, pczTmpBuf1, 85 );
ptr = ptr + 85 ;
}
/* loop for read the transaction until all has received */
do
{
/*
** read the left of the transaction from the socket
*/
if( iLeft > MAX_DATA_LEN )
iRead = MAX_DATA_LEN;
else
iRead = iLeft;
iLen = u_read( communfd, pczTmpBuf, iRead );
if( iLen <= 0 )
{
alarm( 0 );
return ( -1113 );
}
/*
** add the string ever time
*/
memcpy( ptr, pczTmpBuf, iLen );
iLeft = iLeft - iLen;
ptr = ptr + iLen;
}
while( iLeft > 0 ); /* all has recevied */
if (iHeadFlag == SYNC_ASCII_FOUR_NONE_HEAD_SYNC_LRC) {
memset (pczTmpBuf, 0, sizeof (pczTmpBuf));
iLeft = 2;
ptr = pczTmpBuf;
do {
if (iLeft > MAX_DATA_LEN)
iRead = MAX_DATA_LEN;
else
iRead = iLeft;
iLen = u_read (communfd, ptr, iRead);
if (iLen <= 0) {
alarm (0);
return (-1113);
}
iLeft = iLeft - iLen;
ptr = ptr + iLen;
} while (iLeft > 0);
if (pczTmpBuf[0] != 0x03 ) {
alarm (0);
return (-1116);
}
for (i = 0; i < iAll; i++) {
cLRC = cLRC ^ pczTranBuf[i];
}
cLRC = cLRC ^ 0x03;
if (pczTmpBuf[1] != cLRC) {
alarm (0);
return (-1117);
}
}
/*
** read the socket of transaction is ok
*/
alarm( 0 );
return( iAll );
}
else
{
return( -1100 );
}
}