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

📄 modbus_tcp.c.svn-base

📁 linux 平台, modbus tcp 协议的简单实现.
💻 SVN-BASE
字号:
/******************************************************************************
 *
 * Copyright (c) 2008 Shanghai IS Software
 *
 * All rights reserved
 *
 * $Revision$
 *
 * $LastChangedBy$
 *
 * $LastChangedData$
 *
 * Description: modbus tcp server
 *
 * Revision History:
 * 2008/09/18 14:33 by lcj
 * #1.created
 *
 *****************************************************************************/
#include "md/md_manager.h"
#include "md/md_info.h"
#include "md/md_reg.h"


#include "modbus_tcp/modbus_tcp.h"


int  get_value(unsigned char *temp,unsigned char *buff_data)
{
	int result,i,j;
	MD_info* info;
	MD_reg_info *reg_info;
	int port = V_PORT;
	int addr = V_ADDR;
	unsigned short start_addr;
	unsigned short num;
	unsigned short data[16];
	unsigned char *p = temp;

	
	start_addr = (unsigned short)(MAKEWORD(buff_data[2],buff_data[3]));
	num	= (unsigned short)(MAKEWORD(buff_data[4],buff_data[5]));

	
	result = init_MD_manager(2, 5, 500);
	if(result)
	{
		info = get_MD_info(port,addr);
		if(info)
		{
			for( i = 0; i < num; i++ )
			{
				reg_info = (MD_reg_info *)get_reg_info(info,(start_addr + i ));
				if (reg_info)
				{
					if ( MD_STATUS_NORMAL == reg_info->status )
						get_MD_reg_value(info,(start_addr+i),&data[i]);
					else 
					{
						printf("V_modbus Value is not Set!\n");
						exit(0);
					}	
				}
			}
		}
	}
	for ( j = 0, i = 0; i < num; i++,j+=2)
	{
		p[j] = (data[i] & 0xff00) >> 8;
		p[j+1] = data[i] & 0x00ff;
	
	}
	
	return 0;
	
}

int num2str(unsigned char *buff,unsigned char *buf)
{
	unsigned char *p = buf;
	int i,j, len ;
	
	len = p[5] + 6;

	for (j = 0, i = 0; i < len; i++)
	{
		sprintf(&buff[j++],"%x ",((*p & 0xF0) >> 4));
		sprintf(&buff[j++],"%x ",(*p++ & 0xF));
	}

	buff[j] = '\0';
			
	return 0;
}

void sendframe(int fd,unsigned char *buf,struct sockaddr_in cl_addr )
{
	int i,n,len;
	unsigned char *p = buf;
	unsigned char buff[32];

	num2str(buff,buf);

	n = sendto(fd,buff,sizeof(buff),0,(struct sockaddr_in *)&cl_addr,sizeof(cl_addr));
	if ( n < 0 || n > sizeof(buff) )	
	{
		printf("writen error!\n");
		exit(0);
	}
	return;
}

int parseframe(int fd,unsigned char *buf_top,unsigned char *buf_data,struct sockaddr_in cl_addr )
{
	int ret,flag = 0;
	int i;
	unsigned char *ptr = buf_data;
	unsigned char  tmp[MAX_RX] ,rx_buf[MAX_RX];
	unsigned char *p = rx_buf;

	for ( i = 0; i < 5; i++ )  
		rx_buf[i] = buf_top[i];

	rx_buf[6] = ptr[0]; // dev_addr
	rx_buf[7] = ptr[1]; // command
	rx_buf[8] = ((unsigned short)MAKEWORD(buf_data[4],buf_data[5]))*2; // num
	rx_buf[5] = 3 + rx_buf[8]; // len

	for ( i = 0; i < 9; i++ )
		p++;

	switch(ptr[1])
	{
		case 0x03:
			ret = get_value(tmp,buf_data);
			if ( ret < 0 )
			{
				printf("Get Value error!\n");
				exit(-1);
			}
			flag = 1;
			break;
		case 0x06:
			printf("command is write!\n");
			break;
		default:
			printf("command error!\n");
			break;
	}

	if ( flag == 0 )
	{	
		printf("commmand is not supply!\n");
		exit(0);
	}
	
	strncpy(p,tmp,rx_buf[8]);
	
	sendframe(fd,rx_buf,cl_addr);
	
	return 0;
}

 int do_it(int connfd,struct sockaddr_in cl_addr)
 {
 	int i,temp;
	int fd = connfd;
	ssize_t n;
	unsigned char buf_top[6];
	unsigned char buf_data[MAXLINE];
	struct sockaddr_in	addr = cl_addr;
	int addr_len = sizeof(struct sockaddr_in);
		
	n = recvfrom(fd,buf_top,6,0,(struct sockaddr *)&addr,&addr_len);
	if ( n < 0 || n > 6 )
	{
		printf("read error!\n");
		return -1;
	}
	
	if ((MAKEWORD(buf_top[2],buf_top[3]) != 0) || (MAKEWORD(buf_top[4],buf_top[5])) > 0xff )
	{
		printf("modbus tcp data error!\n");
		return -1;
	}
	n = recvfrom(fd, buf_data,(MAKEWORD(buf_top[4],buf_top[5])),0,(struct sockaddr *)&addr,&addr_len);
	if ( n < 0 || n > (MAKEWORD(buf_top[4],buf_top[5])))
	{
		printf("read error!\n");
		return -1;
	}	
	parseframe(fd,buf_top,buf_data,addr);
	
	return ;
}


void sig_chld(int signo)
{
	pid_t 	pid;
	int 	stat;

	while ((pid = waitpid(-1,&stat,WNOHANG)) > 0)
		printf("child %d terminated\n",pid);

	return;
}

int main(int argc, char **argv)
{
	int listenfd,connfd;
	pid_t childpid;
	socklen_t	clilen;
	struct sockaddr_in	cliaddr,servaddr;
	
	listenfd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
	if ( listenfd < 0 )
	{
		printf("socket error!\n");
		exit(0);
	}

	bzero(&servaddr,sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
	servaddr.sin_port = htons(MODBUS_TCP_PORT);
	
	bind(listenfd,(SA *)&servaddr,sizeof(servaddr));

	listen(listenfd,LISTENQ);

	signal(SIGCHLD,sig_chld);

	while (1)
	{
		clilen = sizeof(cliaddr);

		if ((connfd = accept(listenfd,(SA *)&cliaddr,&clilen)) < 0 )
		{
			if ( errno == EINTR )
				continue;
			else 
				printf(" accept error!\n");
		}
		
		if ( 0 == (childpid = fork())) // child process
		{
			close(listenfd);
						
			do_it(connfd,cliaddr);
			
			close(connfd);
			exit(0);
		}
		
		close(connfd);
	}

	return 0;
}

 

⌨️ 快捷键说明

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