⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 comlib.c

📁 linux系统下面实现modbustcp协议的通讯
💻 C
字号:

/*自己的函数*/
unsigned char * changeHiLow(unsigned char *ptr)
{
    unsigned char temp[2];
	temp[0]=*(ptr+1);
	temp[1]=*(ptr);
	*(ptr+0)=temp[0];
	*(ptr+1)=temp[1];
    return (ptr);
}

int my_atoi(char *ptr)
{
    char temp[12];
	int ret,i;

	temp[11]=0x00;
    memcpy(temp,ptr,11);

	//debug_16((unsigned char *) temp,11);
	for(i=0;i<11;i++)
	{   
		if(0x30<=temp[i] && 0x39>=temp[i] )
			;
		else
			temp[i]=0;	
	}

    //debug_16((unsigned char *) temp,11);
	for(i=0;i<11;i++)
	{   
		if(0!=temp[i] )
		{
		   ret=atoi(&temp[i]);
		   return(ret);
		}
	}
	return(-1);
}


/*显示函数*/
/*
int debug_16(char *ptr, int len)
{   
	unsigned int i;
	printf("[DEBUG]: ");
	for(i=0;i<len;i++)
	{
		if(15<*ptr)  printf("%x ",*ptr);
		else         printf("0%x ",*ptr);
		ptr++;
	}
	printf("<%d>\r\n",len);
	return(0);
}

int debug_pid(char *ptr)
{
    printf("[DEBUG]: ");
	printf("%s",ptr);
	printf(" <%d> , [PID]: %d\r\n",strlen(ptr),getpid());
	return(0);
}

int debug_str(char *ptr)
{
    printf("[DEBUG]: ");
	printf("%s",ptr);
	printf(" <%d> \r\n",strlen(ptr));
	return(0);
}*/

/*时间函数*/
TIMESTRU GetTime()
{
	TIMESTRU timestru;
	
	time_t time1;
	struct tm * when;
	
	time(&time1);
	when = localtime(&time1);
	
	timestru.nYear = when->tm_year + 1900;
	timestru.nMon = when->tm_mon + 1;
	timestru.nDay = when->tm_mday;
	
	timestru.nHour = when->tm_hour;
	timestru.nMin = when->tm_min;
	timestru.nSec = when->tm_sec;
	
	return timestru;
}

TIMESTRU DisplayTime(time_t time1)
{
	TIMESTRU timestru;
	struct tm * when;
	//time(&time1);
	when = localtime(&time1);
	
	timestru.nYear = when->tm_year + 1900;
	timestru.nMon = when->tm_mon + 1;
	timestru.nDay = when->tm_mday;
	
	timestru.nHour = when->tm_hour;
	timestru.nMin = when->tm_min;
	timestru.nSec = when->tm_sec;
	
	return timestru;
}

TIMESTRU GetOffsetTime(TIMESTRU timestru, int nOffsetSec)
{
	TIMESTRU timestruAfter;
	time_t ttime;
	struct tm when;
	
	memset(&when, 0, sizeof(when));
	when.tm_year = timestru.nYear - 1900;
	when.tm_mon  = timestru.nMon - 1;
	when.tm_mday = timestru.nDay;
	when.tm_hour = timestru.nHour;
	when.tm_min  = timestru.nMin;
	when.tm_sec  = timestru.nSec;
	
	ttime = mktime(&when) + nOffsetSec;
	
	when = *localtime(&ttime);
	
	timestruAfter.nYear = when.tm_year + 1900;
	timestruAfter.nMon = when.tm_mon + 1;
	timestruAfter.nDay = when.tm_mday;
	timestruAfter.nHour = when.tm_hour;
	timestruAfter.nMin = when.tm_min;
	timestruAfter.nSec = when.tm_sec;
	
	return timestruAfter;
}

/*调试记录函数*/
int PrintLog(FILE* pfile, const char * pformat, ...)
{
	va_list _va_list;
	TIMESTRU timestru;
	char szBuf[MAXBUF];
	int nLen;
	if (pformat == NULL || pfile == NULL) return -1; 	/* 判断指针是否正确*/
	timestru = GetTime();
	nLen = sprintf(szBuf, " %04d.%02d.%02d %02d:%02d:%02d [%d]: ",
		timestru.nYear, timestru.nMon, timestru.nDay,
		timestru.nHour, timestru.nMin, timestru.nSec, getpid());
		
	va_start(_va_list, pformat); 				/* 初始化变长参数列表 */
	nLen += vsprintf(szBuf+nLen, pformat, _va_list); 	/* 传递变长参数 */
	va_end(_va_list); 					/* 结束使用变长参数列表 */
	
	nLen += sprintf(szBuf + nLen, "\n");			/* 添加换行符 */
	if (fputs(szBuf, pfile) != EOF && fflush(pfile) != EOF) return 0;/*  输出并刷新文件流 */
	return -2;						/* 错误返回 */
}

int PrintTraceLog(const char* pformat, ...)
{
 	va_list _va_list;
	char szBuf[MAXBUF];
 	FILE *fp;
 	int ret;
	if (pformat == NULL) return -1; 	/* 判断指针是否正确*/
		
 	va_start(_va_list, pformat);		  
 	vsprintf(szBuf, pformat, _va_list);     
 	va_end(_va_list);                      

 	if ((fp = fopen(TRACE_FILE, "w")) != NULL)
 	{
 		ret = PrintLog(fp, szBuf);	/* 写日志文件 */
 		fclose(fp);			/* 关闭日志文件 */
	 	return(ret);
 	}
 	return -1;
}



int my_isprint( int ch ) /*判断字符c是否为可打印字符(含空格)。当c为可打印字符(0x20-0x7e)时,返回非零值,否则返回零*/
{ 
	return (unsigned int)(ch - ' ') < 127u - ' '; 
}
/*
U或u 放在常量后面就是把它转换成unsigned int类型;类似的还有,L或l(long int),F或f(float); 
我猜你也许不太了解为什么要把它变成unsigned int类型?第一个中吧:因为空白符(9-13对应10进制
+空格)如果ch<9,那ch-9就会变负数也确时小于5,答案就不对了!所以就想到了把它转换成unsigned
int!把一个负数变成无符号型的会变成非常大的一个整数!
*/

int PrintHexLog(FILE* pfile, void * pData, int nSize)
{
	char cLine[16], *pcData;
	char szBuf[MAXBUF + 1];
	int nPos, nLineSize, nLine, nLen, n;
	if (pfile == NULL || pData == NULL) return -1;
	
	pcData = (char*)pData;
	nLine = 1;
	nLen = sprintf(szBuf, "address[%08X] size[%d]\n", pData, nSize);
	for (nPos = 0; nPos < nSize; nLine++)
	{
		nLineSize = min(nSize - nPos, 16);		/* 防止最后一行数据不足 */
		memcpy(cLine, pcData + nPos, nLineSize);
		nPos += nLineSize;
		nLen += sprintf(szBuf + nLen, "[%02d]:  ", nLine);
		for (n = 0; n < nLineSize; n++)
		{
			if (n == 8) nLen += sprintf(szBuf + nLen, " ");/* 第8个字节后空格 */
			nLen += sprintf(szBuf + nLen, "%02X ", cLine[n] & 0x00FF);
		}
		for (n = nLineSize; n < 16; n++)	/* 最后一行补空格 */
		{
			if (n == 8) nLen += sprintf(szBuf + nLen, " ");
			nLen += sprintf(szBuf + nLen, "   ");
		}
		nLen += sprintf(szBuf + nLen, " :");
		for (n = 0; n < nLineSize; n++)		/* 以字符显示内存数据 */
		{
			if (!my_isprint(cLine[n])) cLine[n] = '.';	/* 以“.”显示非打印字符 */
			nLen += sprintf(szBuf + nLen, "%c", cLine[n]);
		}
		nLen += sprintf(szBuf + nLen, "\n");
	}
	PrintLog(pfile, szBuf);
	return 0;
}

int PrintTraceHexLog(void * pData, int nSize)
{
 	FILE *fp;
 	int ret;
 	if ((fp = fopen(TRACE_FILE, "a")) != NULL)
 	{
 		ret = PrintHexLog(fp, pData, nSize);	/* 写日志文件 */
 		fclose(fp);				/* 关闭日志文件 */
	 	return(ret);
 	}
 	return -1;
}

int Verify(int bStatus, const char* szBuf, const char* szFile, int nLine)
{
	FILE *fp;
	char szFileLine[128], szError[128];
	if (!bStatus)
	{
		memset(szFileLine, 0, sizeof(szFileLine));       
		memset(szError, 0, sizeof(szError));
		if (errno != 0) sprintf(szError, "\t> %0.64s\n", strerror(errno));
		if (szFile == NULL) strcpy(szFileLine, "\t> Invalid file name");
		else sprintf(szFileLine, "\t> In line %d file %0.32s", nLine, szFile);
		if (szBuf == NULL)  szBuf = "";
		fp = fopen(TRACE_FILE, "a");
		if (fp != NULL)
		{
			PrintLog(fp, "%s[%d]\n%s%s", szBuf, getpid(), szError, szFileLine);
			fclose(fp);
		}
		errno = 0;
	}
	return bStatus;
}

/*UDP函数*/
int CreateUdpSock(int * pnSock, int nPort)
{
	struct sockaddr_in addrin;
	struct sockaddr *paddr = (struct sockaddr *)&addrin;

	ASSERT(pnSock != NULL && nPort > 0);
	memset(&addrin, 0, sizeof(addrin));
	/* 协议地址组包 */
	addrin.sin_family = AF_INET;			/* 协议名 */
	addrin.sin_addr.s_addr = htonl(INADDR_ANY);	/* 自动分配地址 */
	addrin.sin_port = htons(nPort);			/* 端口号 */
	/* 组装系统调用socket和bind */
	ASSERT((*pnSock = socket(AF_INET, SOCK_DGRAM, 0)) > 0);	/* 创建UDP套接字描述符 */
	if (VERIFY(bind(*pnSock, paddr, sizeof(addrin)) >= 0) )	/* 命名套接字 */
		return 0;					/* 准备成功,正确返回 */
	VERIFY(close(*pnSock) == 0);				/* 准备失败,关闭套接字描述符 */
	return 1;
}
/*
int SendMsgByUdp(int nSock,void * pMsg, int nSize, char * szAddr, char *port)
{
	struct sockaddr_in addrin;
    	//ASSERT((nSock = socket(AF_INET, SOCK_DGRAM, 0)) > 0);	// 创建UDP套接字描述符 
	memset(&addrin, 0, sizeof(struct sockaddr));
	// 接收方的协议地址组包 
	addrin.sin_family = AF_INET;			// 协议名 
	//addrin.sin_addr.s_addr = inet_addr(szAddr);	 
	memcpy((char *)&addrin.sin_addr.s_addr ,szAddr,4);// 接收方的地址
	//addrin.sin_port = htons(nPort);			// 接收方的服务端口号
	memcpy((char *)&addrin.sin_port ,port,2);
	VERIFY(sendto(nSock, pMsg, nSize, 0,		// 发送数据到接收方
	             (struct sockaddr *)&addrin,
	             sizeof(addrin)) > 0);
	//close (nSock);					// 关闭套接字 
	return 0;
}*/

int SendMsgByUdp(void * pMsg, int nSize, char * szAddr, int nPort)
{
	int nSock;
	struct sockaddr_in addrin;
    	ASSERT((nSock = socket(AF_INET, SOCK_DGRAM, 0)) > 0);	// 创建UDP套接字描述符 
	memset(&addrin, 0, sizeof(struct sockaddr));
	// 接收方的协议地址组包 
	addrin.sin_family = AF_INET;			// 协议名 
	addrin.sin_addr.s_addr = inet_addr(szAddr);	// 接收方的地址 
	addrin.sin_port = htons(nPort);			// 接收方的服务端口号
	VERIFY(sendto(nSock, pMsg, nSize, 0,		// 发送数据到接收方
	             (struct sockaddr *)&addrin,
	             sizeof(addrin)) > 0);
	close (nSock);					// 关闭套接字 
	return 0;
}
/*这个接收函数有问题暂时不用他	
int RecvMsgByUdp(int nFile, void * pData, int * pnSize) 
{
	int nSize;
	
	ASSERT((*pnSize=recvfrom(nFile, pData, *pnSize, 0 , NULL, NULL)) > 0);
	return 0;
}*/
/*TCP函数*/
int CreateSock(int* pSock, int nPort, int nMax)
{
	struct sockaddr_in addrin;
	struct sockaddr *paddr = (struct sockaddr *)&addrin;

	ASSERT(pSock != NULL && nPort > 0 && nMax > 0);
	
	memset(&addrin, 0, sizeof(addrin));
	/* 协议地址组包 */
	addrin.sin_family = AF_INET;			/* 协议名 */
	addrin.sin_addr.s_addr = htonl(INADDR_ANY);	/* 自动分配地址 */
	addrin.sin_port = htons(nPort);			/* 端口号 */
	ASSERT((*pSock = socket(AF_INET, SOCK_STREAM, 0)) > 0);	/* 创建TCP套接字描述符 */
	if (VERIFY(bind(*pSock, paddr, sizeof(addrin)) >= 0) &&	/* 命名套接字 */
	    VERIFY(listen(*pSock, nMax) >= 0))		/* 套接字进入侦听状态 */
		return 0;				/* 准备成功,正确返回 */
	VERIFY(close(*pSock) == 0);			/* 准备失败,关闭套接字描述符 */
	return 1;
}

int AcceptSock(int * pSock, int nSock)
{
	struct sockaddr_in addrin;
	int lSize;
	ASSERT(pSock != NULL && nSock > 0);
	while (1)
	{
		lSize = sizeof(addrin);
		memset(&addrin, 0, sizeof(addrin));
		/* 阻塞接收客户端连接请求,并创建新的套接字描述符(linux 与 unix 有点不一样) */
		if ((*pSock = accept(nSock, (struct sockaddr *)&addrin, (socklen_t*)&lSize)) > 0)
			return 0;
		/* 调用accept过程中接收到到信号,调用中断 */
		else if (errno == EINTR)	continue;
		else  	ASSERT(0);
	}
}





















⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -