首页 > 代码库 > 一种远程修改sqlite数据库的方法

一种远程修改sqlite数据库的方法

一、实际需求

     工业设备DA660是专门用来实现工业上可编程设备之间交换信息的交换机。现在要使得DA660采集下行设备的实时数据,然后传送到上位机显示。上位机还可以远程修改DA660的数据库配置。

二、数据库设计

     我在DA660中设计了sqlite3数据库,名为da660.db,里面存放很多表,其中有一张表示baseinfo,其结构定义如下:


通道号是从0到15之间的正整数,从机地址是从0到256之间的正整数,设备类型定义为0到5之间的正整数,设备类型可从{“xz2000”, “xz3000”, “xz3100”, “xz3500”,“xz6000”}匹配得到,波特率定义为0到4之间的正整数,波特率可从{“2400”, “4800”,“9600”,“192000”}。
注意:设备类型和波特率这样定义的原因是即节省了存储空间,又便于网络中传输和解析。

三、 本地数据库创建

/*
 * Database Init tool
 * */
#include <stdio.h>
#include <stdlib.h>
#include "sqlite3.h"
sqlite3 *db;
/*
 * return 0 if database can be created  successfully else return -1
 * */
int InitDatabase() {
	int rc; 
	char *sql;
	char *zErrMsg = NULL;    // error string 

	rc = sqlite3_open("da660.db", &db);  // open or create a database
	if(rc) {
		perror("can not create or open da660.db...!\n");
		rc = -1;
	}
	else {
		/*
		 * create baseinfo table
		 * */
		sql = "CREATE TABLE baseinfo(port INTEGER, addr INTEGER, type INTEGER, bps INTERGER, primary key(port, addr));";  
		rc = sqlite3_exec(db, sql, 0, 0, &zErrMsg);   // create data table
		if(rc != SQLITE_OK) {
			perror("create baseinfo table failed... !\n");
			rc = -1;
		}
		/*
		 * create xz3100 realtime_data table
		 * */
		sql = "CREATE TABLE xz3100_realtime_data(port INTEGER, addr INTEGER, 			   D0 INTEGER, D1 INTERGER, D2 INTEGER, D3 INTEGER, D4 INTEGER, D5 INTEGER, D6 INTEGER, D7 INTEGER, D8 INTEGER, D9 INTEGER, 			   D10 INTEGER, D11 INTERGER, D12 INTEGER, D13 INTEGER, D14 INTEGER, D15 INTEGER, D16 INTEGER, D17 INTEGER, D18 INTEGER, D19 INTEGER, 			   D20 INTEGER, D21 INTERGER, D22 INTEGER, D23 INTEGER, D24 INTEGER, D25 INTEGER, D26 INTEGER, D27 INTEGER, D28 INTEGER, D29 INTEGER, 			   D30 INTEGER, D31 INTERGER, D32 INTEGER, D33 INTEGER, D34 INTEGER, D35 INTEGER, D36 INTEGER, D37 INTEGER, D38 INTEGER, D39 INTEGER, 			   D40 INTEGER, D41 INTERGER, D42 INTEGER, D43 INTEGER, D44 INTEGER, D45 INTEGER, D46 INTEGER, D47 INTEGER, D48 INTEGER, D49 INTEGER, 			   D50 INTEGER, D51 INTERGER, D52 INTEGER, D53 INTEGER, D54 INTEGER, D55 INTEGER, D56 INTEGER, D57 INTEGER,									   primary key(port, addr));";  
		rc = sqlite3_exec(db, sql, 0, 0, &zErrMsg);   // create data table
		if(rc != SQLITE_OK) {
			perror("create xz3100 realtime data table failed... !\n");
			rc = -1;
		}
		/*
		 * create xz3100 SOE table
		 * */
		sql = "CREATE TABLE xz3100_soe_data(port INTEGER, addr INTEGER, 			   D0 INTEGER, D1 INTERGER, D2 INTEGER, D3 INTEGER, D4 INTEGER, D5 INTEGER, D6 INTEGER, D7 INTEGER,  D8 INTEGER,  D9 INTEGER,  			   D10 INTEGER, D11 INTERGER,  			   primary key(port, addr));";  
		rc = sqlite3_exec(db, sql, 0, 0, &zErrMsg);   // create data table
		if(rc != SQLITE_OK) {
			perror("create xz3100 soe table failed... !\n");
			rc = -1;
		}
		/*
		 * create xz3100 action table 
		 * */
		sql = "CREATE TABLE xz3100_action_data(port INTEGER, addr INTEGER, 			   D0 INTEGER, D1 INTERGER, D2 INTEGER, D3 INTEGER, D4 INTEGER, D5 INTEGER, D6 INTEGER, D7 INTEGER, D8 INTEGER, D9 INTEGER,  			   D10 INTEGER, D11 INTERGER,  			   primary key(port, addr));";  
		rc = sqlite3_exec(db, sql, 0, 0, &zErrMsg);   // create data table
		if(rc != SQLITE_OK) {
			perror("create xz3100 action table failed... !\n");
			rc = -1;
		}
		/*
		 * create xz3100 opeing table 
		 * */
		sql = "CREATE TABLE xz3100_opening_data(port INTEGER, addr INTEGER, 			   D0 INTEGER, D1 INTERGER, D2 INTEGER, D3 INTEGER, D4 INTEGER, D5 INTEGER, D6 INTEGER, D7 INTEGER, D8 INTEGER, D9 INTEGER,  			   D10 INTEGER, D11 INTERGER, D12 INTEGER, D13 INTEGER, D14 INTEGER, D15 INTEGER, D16 INTEGER, D17 INTEGER, D18 INTEGER, D19 INTEGER, 			   primary key(port, addr));";  
		rc = sqlite3_exec(db, sql, 0, 0, &zErrMsg);   // create data table
		if(rc != SQLITE_OK) {
			perror("create xz3100 opening table failed... !\n");
			rc = -1;
		}
		/*
		 * create xz3100 arg_data table
		 * */
		sql = "CREATE TABLE xz3100_arg_data(port INTEGER, addr INTEGER, 			   D0 INTEGER, D1 INTERGER, D2 INTEGER, D3 INTEGER, D4 INTEGER, D5 INTEGER, D6 INTEGER, D7 INTEGER, D8 INTEGER, D9 INTEGER, 			   D10 INTEGER, D11 INTERGER, D12 INTEGER, D13 INTEGER, D14 INTEGER, D15 INTEGER, D16 INTEGER, D17 INTEGER, D18 INTEGER, D19 INTEGER, 			   D20 INTEGER, D21 INTERGER, D22 INTEGER, D23 INTEGER, D24 INTEGER, D25 INTEGER, D26 INTEGER, D27 INTEGER, D28 INTEGER, D29 INTEGER, 			   D30 INTEGER, D31 INTERGER, D32 INTEGER, D33 INTEGER, D34 INTEGER, D35 INTEGER, D36 INTEGER, D37 INTEGER, D38 INTEGER, D39 INTEGER, 			   D40 INTEGER, D41 INTERGER, D42 INTEGER, D43 INTEGER, D44 INTEGER, D45 INTEGER, D46 INTEGER, D47 INTEGER, D48 INTEGER, D49 INTEGER, 			   D50 INTEGER, D51 INTERGER, D52 INTEGER, D53 INTEGER, D54 INTEGER, D55 INTEGER, D56 INTEGERR,									   primary key(port, addr));";  
		rc = sqlite3_exec(db, sql, 0, 0, &zErrMsg);   // create data table
		if(rc != SQLITE_OK) {
			perror("create xz3100 arguments data table failed... !\n");
			rc = -1;
		}
		/*
		 * create xz3100 statistic_data table
		 * */
		sql = "CREATE TABLE xz3100_statistic_data(port INTEGER, addr INTEGER, 			   D0 INTEGER, D1 INTERGER, D2 INTEGER, D3 INTEGER, D4 INTEGER, D5 INTEGER, D6 INTEGER, D7 INTEGER, D8 INTEGER, D9 INTEGER, 			   D10 INTEGER, D11 INTERGER, D12 INTEGER, D13 INTEGER, D14 INTEGER, D15 INTEGER, D16 INTEGER, D17 INTEGER, D18 INTEGER, D19 INTEGER, 			   D20 INTEGER, D21 INTERGER, D22 INTEGER, D23 INTEGER, D24 INTEGER, D25 INTEGER,									   primary key(port, addr));";  
		rc = sqlite3_exec(db, sql, 0, 0, &zErrMsg);   // create data table
		if(rc != SQLITE_OK) {
			perror("create xz3100 statistic data table failed... !\n");
			rc = -1;
		}
		if(!rc) {
			printf("Database Init Successfully!\n");
		}
	}
	/*
	 * never to forget to close the db
	 * */
	sqlite3_close(db);

	return rc;
}
int main() {
	if(InitDatabase()) {
		perror("Data Init failed!\n");
		exit(EXIT_FAILURE);
	}

	return 0;
}

四、本地数据库配置

/*
 * Database configure tool
 * */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sqlite3.h"
#define SIZE 128
typedef unsigned char uchar;
sqlite3 *db;
sqlite3_stmt *state;  // associate with sql 
char *equipmentType[] = {"xz2000", "xz3000", "xz3100", "xz3500", "xz6000"};
char *bpsArray[] = {"2400", "4800", "9600", "192000"};
/*
 * to insert a record into baseinfo table 
 * return 0 if insert successfully else return -1
 * type and bps should be the index of corresponding array
 * */
int Insert_baseinfo(uint port, uint addr, uint type, uint bps) {
	int rc;
	char *zErrMsg = NULL;
	char insert_sql[SIZE];
	/*
	 * to open da660.db 
	 * */
	rc = sqlite3_open("da660.db", &db);
	if(rc) {
		perror("da660.db open failed...!\n");
		rc = -1;
	}
	else {
		/*
		 * insert data record
		 * */
		memset(insert_sql, 0, sizeof(insert_sql));
		sprintf(insert_sql, "INSERT INTO baseinfo(port, addr, type, bps) VALUES(%u, %u, %u, %u)", port, addr, type, bps);
		rc = sqlite3_exec(db, insert_sql, 0, 0, &zErrMsg); // execute sql statement and insert data record
		if(rc == SQLITE_OK) {
			printf("insert one data record success...!\n");
		}
		else {
			perror("insert one data record failure...!\n");
			rc = -1;
		}
		sqlite3_close(db);  // never to forget to close the db
	}

    return rc;
}
/*
 * to delete a data record from baseinfo table 
 * return 0 if insert successfully else return -1
 * */
int Delete_baseinfo(uint port, uint addr) {
	int rc;
	int nRow, nColumn;
	char *zErrMsg = NULL;
	char **dbResult;  // point to two dimension table
	char select_sql[SIZE];
	char delete_sql[SIZE];
	/*
	 * to open da660.db 
	 * */
	rc = sqlite3_open("da660.db", &db);
	if(rc) {
		perror("da660.db open failed...!\n");
		rc = -1;
	}
	else {
		/*
		 * first query the data record
		 * */
		memset(select_sql, 0, sizeof(select_sql));
		sprintf(select_sql, "select * from baseinfo where port = %u and addr = %u", port, addr);
		rc = sqlite3_get_table(db, select_sql, &dbResult, &nRow, &nColumn, &zErrMsg);
		if(rc != SQLITE_OK) {
			perror("database query error!\n");
			rc = -1;
		}
		else if(!nRow) {
			perror("data record does not exist!\n");
			rc = -1;
		}
		/*
		 * delete the data record
		 * */
		else {
			memset(delete_sql, 0, sizeof(delete_sql));
			sprintf(delete_sql, "delete from baseinfo where port = %u and addr = %u", port, addr);
			rc = sqlite3_exec(db, delete_sql, 0, 0, &zErrMsg); // execute sql statement and delete data record
			if(rc == SQLITE_OK) {
				printf("delete one data record success...!\n");
			}
			else {
				perror("delete one data record failure...!\n");
				rc = -1;
			}
		}
		sqlite3_free_table(dbResult); // never to forget to free the query table
		sqlite3_close(db);  // never to forget to close the db
	}

    return rc;
}
/*
 * query records from baseinfo table in terms with port
 * return 0 if query success else return -1
 * */
int Query_baseinfo(uint port) {
	int rc;
	int nRow, nColumn;
	int row, col;
	int index;
	uint type;   // the equipment type
	uint bps;    // the equipment bps 
	char *zErrMsg = NULL;
	char **dbResult;  // point to two dimension table
	char select_sql[SIZE];
	char *domain, *value; // the domain and value of query table
	/*
	 * to open da660
	 * */
	rc = sqlite3_open("da660.db", &db);
	if(rc != SQLITE_OK) {
		perror("da660.db open failed...!\n");
		rc = -1;
	}
	else {
		/*
		 * to select data record
		 * */
		memset(select_sql, 0, sizeof(select_sql));
		sprintf(select_sql, "select * from baseinfo where port = %u", port);
		/*
		 * to get the two dimension table, nRow means rows and nColumn means cols
		 * */
		rc = sqlite3_get_table(db, select_sql, &dbResult, &nRow, &nColumn, &zErrMsg);
		if(rc != SQLITE_OK) {
			perror("database query failed!\n");
			rc = -1;
		}
		else {
			/*
			 * query statement
			 * */
			index = nColumn;   // the first value should start from nColum
			for(row = 0;row < nRow;row++) {
				printf("-------the %d record----------\n", row + 1);
				for(col = 0;col < nColumn;col++) {
					domain = dbResult[col];
					value = http://www.mamicode.com/dbResult[index];>
五、本地数据库测试

1. 测试数据库正常产生
将交叉编译好的dbCreate文件推入MOXA DA660,在DA660中执行命令./dbCreate,显示如下:



2.  测试数据插入


由测试结果可知,数据能够正常插入,因为baseinfo表中port和addr被定义为主码,因此测试结果符合设定要求。

3. 测试数据查询


4. 测试数据删除




六、远程修改数据库的方法

客户端f发送数据库操作报文,包括查询,删除和插入,DA660解析报文并发回回送报文。



七、DA660里数据库线程

数据库线程在端口4001(专门为数据库操作而设置)不停侦测有无客户端连接请求,如果有响应该请求。

#include <sys/time.h>
#include "database.h"
#include "socket.h"
#include "serial.h"
#include "xz3100.h"
#include <signal.h>
#define db_port 4001
#define realtime_data_port 4002
#define equipment_control_port 4003
char *equipmentType[] = {"xz2000", "xz3000", "xz3100", "xz3500", "xz6000"};
char *bpsArray[] = {"2400", "4800", "9600", "192000"};
baseinfoNode *baseinfoNode_array[16];
port_lock_type lock_array[16];
xz3100_realtime_data_Node *xz3100_realtime_data_Node_array[16];
xz3100_soe_data_Node *xz3100_soe_data_Node_array[16];
xz3100_action_data_Node *xz3100_action_data_Node_array[16];
xz3100_opening_data_Node *xz3100_opening_data_Node_array[16];
xz3100_arg_data_Node *xz3100_arg_data_Node_array[16];
xz3100_statistic_data_Node *xz3100_statistic_data_Node_array[16];

uint first_addr, last_addr;
struct timeval start, end;
unsigned long timer;
uint portInit[16];   // whether the port is initialized, 0 or 1
/*
 * db_thread
 * accept request about database from client 
 * */
void *db_thread(void *ptr) {
	uchar sbuf[BUFFER_LEN];
	uchar rbuf[BUFFER_LEN];
	uchar clientaddr[BUFFER_LEN];
	int len;
	int s_len, r_len;
	int serverfd, clientfd;
	int i;
	/*
	 * Init TCP Server
	 * */
	TCPServerInit(db_port, &serverfd);
	if(serverfd < 0) {
		perror("failed to init server!\n");
		exit(EXIT_FAILURE);
	}
	/*
	 * to listen and connect the client 
	 * */
	while(1) {
		TCPServerWaitConnection(serverfd, &clientfd, clientaddr); // if there is no connection request, blocked here
		if(clientfd < 0) {
			perror("failed to connect client!\n");
			exit(EXIT_FAILURE);
		}
		while(1) {
			len = TCPBlockRead(clientfd, rbuf, BUFFER_LEN); // blocked until there is data coming into the port
			if(len <= 0) {  // if can not read data, sleep and then continue
				sleep(1);
				break;
			}
			else {
				Database_resolve(sbuf, rbuf, &s_len, &r_len);
				if(TCPWrite(clientfd, sbuf, s_len) == s_len) {
					printf("db control data have been sent...!\n");
			//		for(i = 0;i < s_len;i++) {       Testing: db control paragram is OK!
			//			printf("%d\t", sbuf[i]);
			//		}
//					printf("\n");
				}
				else perror("db control data sent error...!\n");
			}
		}
	}
	TCPConnectionClose(serverfd);

	return 0;
}
/*
 * find the equipment type from baseinfoNode array
 * @port: port
 * @addr: equipment addr
 * @type: equipment type
 * return 0 if find successfully else return -1
 * */
int find_equipment_type(uint port, uint addr, uint *type) {
	baseinfoNode *p;
	int rc = 0;
	if(port < 0 || port > 15) {
		printf("query tips: port %d is wrong...!\n", port);
		rc = -1;
	}
	if(!baseinfoNode_array[port]) {
		printf("query tips: port %d is wrong...!", port);
		rc = -1;
	}
	p = baseinfoNode_array[port]->link;
	while(p) {                    // there is a equipment
		if(p->info[0] == port && p->info[1] == addr) {
			*type = p->info[2];
			break;
		}
		p = p->link;
	}
	if(!p) {
		printf("query tips: addr %d is wrong...!", addr);
		rc = -1;
	}

	return rc;
}
/*
 * read all data from 
 * xz3100_realtime_data_Node linklist
 * xz3100_soe_data_Node linklist
 * xz3100_action_data_Node linklist
 * xz3100_opening_data_Node linklist
 * xz3100_arg_data_Node linklist
 * xz3100_statistic_data_Node linklist
 * @port: port
 * @addr: equipment addr
 * @type: equipment type
 * @buf: buf to receive data from equipment link list 
 * @len: the length of buf
 * */
void xz3100_readbuf(uint port, uint addr, uint type, uchar *buf, uint *len) {
	uint index = 0;
	uint i;
	uchar low_8, high_8;
	xz3100_realtime_data_Node *p_realtime_data;
	xz3100_soe_data_Node *p_soe_data;
	xz3100_action_data_Node *p_action_data;
	xz3100_opening_data_Node *p_opening_data;
	xz3100_arg_data_Node *p_arg_data;
	xz3100_statistic_data_Node *p_statistic_data;
	/*
	 * read data from xz3100_realtime_data link list
	 * */
	for(p_realtime_data = http://www.mamicode.com/xz3100_realtime_data_Node_array[port];p_realtime_data != NULL;p_realtime_data = p_realtime_data ->link ) {>
八、客户端代码

#include <signal.h>
#include <setjmp.h>
#include "socket.h"
#include "xz3100.h"
#define BUFFER_LEN 512
char *serveraddr = "192.168.3.127";
char *equipmentType[] = {"xz2000", "xz3000", "xz3100", "xz3500", "xz6000"};
char *bpsArray[] = {"2400", "4800", "9600", "192000"};
uchar sbuf[BUFFER_LEN];
uchar rbuf[BUFFER_LEN];
uchar port, addr, type, bps;
int clientfd;  // just be the global
int db_port = 4001;
int realtime_data_port = 4002;
int control_cmd_port = 4003;
jmp_buf position;
/*
 * to configure the da660 database remotely
 * */
int configureDA660() {
	uchar choice;
	uchar user_choice[50]; // the  no of record which user choice to delete 
	uchar port_addr[50];   // all address in one port should be dynamic created and freed
	uchar typestr[20];
	uchar bpsstr[20];
	int len;
	int i, j;
	int n;
	int try = 0;
	printf("---- Welcome to use DA660 Configure Tool ----\n");
	/*
	 * to initialize client
	 * */
	TCPClientInit(&clientfd);
	if(clientfd < 0) {
		perror("client socket created failed...!\n");
	}
	while(TCPClientConnect(clientfd, serveraddr, db_port)) {
		perror("client connected failed...!\n");
		try++;
		usleep(1e5);
		if(try > 5) {         // to try 5 times to connect
			perror("client connected failed...!\n");
			goto Exit;

		}
	}
	while(1) {
		printf("---- 0:Query data, 1:Delet data, 2:Insert data, 3:Quit ----\n");
		printf("please input your choice:");
		if(scanf("%d", &choice) != 1) {
			perror("input argument invalid...!\n");
			goto Exit;
		}
		/*
		 * to check the user's choice
		 * */
		if(choice != 0 && choice != 1 && choice !=2 && choice != 3) {
			perror("Sorry, you have made wrong choice...!\n");
			goto Exit;
		}
		switch(choice) {
			case 0:
				printf("input the port:");
				if(scanf("%d", &port) != 1) {
					perror("input argument invalid...!\n");
					goto Exit;
				}
				else if(port < 0 || port > 15) {
					perror("port should be 0 ~ 15...!\n");
					goto Exit;
				}
				/*
				 * to send query database paragram
				 * */
				sbuf[0] = 0;
				sbuf[1] = port;
				len = TCPWrite(clientfd, sbuf, 2);
				if(len <= 0) {
					perror("Sorry, data have not been sent from client...!\n");
					goto Exit;
				}
				len = TCPBlockRead(clientfd, rbuf, BUFFER_LEN);
				if(len <= 0 || rbuf[1]) {
					fprintf(stderr, "query port %d failed...!\n", port);
					goto Exit;
				}
				else {
					printf("\t----No----\t----port----\t----addr----\t----type----\t----bps-----\n");
					i = 3;
					len = rbuf[2];
					for(j = 1;j <= len;j++) {
						printf("\t----%2d----\t----%2d----\t----%3d----\t----%6s----\t----%4s-----\n", j, 								rbuf[i], rbuf[i + 1], equipmentType[rbuf[i + 2]], bpsArray[rbuf[i + 3]]);
						port_addr[j - 1] = rbuf[i + 1]; 
						i += 4;
					}
					port_addr[j - 1] = '\0';
				}
				break;
			case 1:
				printf("please input the number of records which need to be deleted, separated with spacing...");
				getchar();
				fgets(user_choice, 50, stdin);
				for(i = 0, j = 0;i < strlen(user_choice);i++) {  // user have make query operation
					if(user_choice[i] != ' ' && user_choice[i] != '\n') {
						j = j * 10 + user_choice[i] - '0';    // to generate the user's choice number
					}
					else {
						if(j - 1 < 0 || j -1 >= strlen(port_addr)) continue;
						sbuf[0] = 1;
						sbuf[1] = port;
						sbuf[2] = port_addr[j - 1];
						j = 0;
						len = TCPWrite(clientfd, sbuf, 3);
						if(len != 3) {
							perror("Sorry, data have not been sent correctly from client...!\n");
							goto Exit;
						}
						len = TCPBlockRead(clientfd, rbuf, BUFFER_LEN);
						if(len <= 0 || rbuf[1]) {
							fprintf(stderr, "delete port %d addr %d failed...!\n", sbuf[1], sbuf[2]);
							goto Exit;
						}
						else if(!rbuf[1]) {
							fprintf(stdout, "delete port %d addr %d successfully...!\n", sbuf[1], sbuf[2]);
						}
					}
				}
				break;
			case 2:
				printf("input the number of records that should be inserted:");
				if(scanf("%d", &n) != 1) {
					perror("input data error, system crash!\n");
					goto Exit;
				}
				if(n <= 50 && n >= 1) {
					for(i = 1;i <= n;i++) {
						printf("the %d record---\n", i);
						/*
						 * input port 
						 * */
						printf("port = ");
						if(scanf("%d", &port) != 1) {
							perror("input data error, system crash!\n");
							goto Exit;
						}
						if(port < 0 || port >= 16) {
							perror("port should be 0 to 15...!");
							i--;
							continue;
						}
						/*
						 * input addr
						 * */
						printf("addr = ");
						if(scanf("%d", &addr) != 1) {
							perror("input data error, system crash!\n");
							goto Exit;
						}
						if(addr < 0 || addr >= 257) {
							perror("port should be 0 to 256...!");
							i--;
							continue;
						}
						/*
						 * input type
						 * */
						printf("type = ");
						if(scanf("%s", typestr) != 1) {
							perror("input data error, system crash!\n");
							goto Exit;
						}
						for(j = 0;j < 5;j++) {
							if(strcmp(equipmentType[j], typestr) == 0) {
								type = j;
							   	break;
							}
						}
						if(j >= 5) {
							perror("equipment type should be xz2000, xz3000, xz3100, xz3500, xz6000...!\n");
							i--;
							continue;
						}
						/*
						 * input bps
						 * */
						printf("bps = ");
						if(scanf("%s", &bpsstr) != 1) {
							perror("input data error, system crash!\n");
							goto Exit;
						}
						for(j = 0;j < 4;j++) {
							if(strcmp(bpsArray[j], bpsstr) == 0) {
								bps = j;
							   	break;
							}
						}
						if(j >=4 ) {
							perror("equiment bps should be 2400, 4800, 9600, 126000...!\n");
							i--;
							continue;
						}
						sbuf[0] = 2;
						sbuf[1] = port;
						sbuf[2] = addr;
						sbuf[3] = type;
						sbuf[4] = bps;
						len = TCPWrite(clientfd, sbuf, 5);
						if(len != 5) {
							perror("Sorry, data have not been sent correctly from client...!\n");
							goto Exit;
						}
						len = TCPBlockRead(clientfd, rbuf, BUFFER_LEN);
						if(len <= 0 || rbuf[1]) {
							fprintf(stderr, "insert data  port %d addr %d failed...!\n", sbuf[1], sbuf[2]);
							goto Exit;
						}
						else if(!rbuf[1]) {
							fprintf(stdout, "insert data  port %d addr %d successfully...!\n", sbuf[1], sbuf[2]);
						}
					}
				}
				break;
			default:
				goto Exit;
		}
	}
Exit: 
	TCPConnectionClose(clientfd);
	return 0;
}
/*
 * to realtime data query remotely
 * */
int queryDA660() {
	uint port, addr;
	uchar sbuf[BUFFER_LEN], rbuf[BUFFER_LEN];
	int len;
	int i, j;
	int n;
	int try = 0;
	char ch;
	printf("---- Welcome to use DA660 Query Tool ----\n");
	/*
	 * to initialize client
	 * */
	TCPClientInit(&clientfd);
	if(clientfd < 0) {
		perror("client socket created failed...!\n");
	}
	while(TCPClientConnect(clientfd, serveraddr, realtime_data_port)) {
		perror("client connected failed...!\n");
		try++;
		usleep(1e5);
		if(try > 5) {         // to try 5 times to connect
			perror("client connected failed...!\n");
			goto Exit;
		}
	}
	/*
	 * input port
	 * */
	printf("input the port:");
	if(scanf("%d", &port) != 1) {
		perror("input argument invalid...!\n");
		goto Exit;
	}
	if(port < 0 || port > 15) {
		perror("port should be 0 ~ 15...!\n");
		goto Exit;
	}
	/*
	 * input addr
	 * */
	printf("input the addr:");
	if(scanf("%d", &addr) != 1) {
		perror("input data error, system crash!\n");
		goto Exit;
	}
	if(addr < 0 || addr >= 257) {
		perror("port should be 0 to 256...!");
		goto Exit;
	}
	/*
	 * to send realtime data query paragram
	 * */
	sbuf[0] = port;
	sbuf[1] = addr;
Next:
	len = TCPWrite(clientfd, sbuf, 2);
	if(len <= 0) {
		perror("Sorry, data have not been sent from client...!\n");
		goto Exit;
	}
	len = TCPBlockRead(clientfd, rbuf, BUFFER_LEN);
	if(len <= 0) {
		fprintf(stderr, "realtime data query from port %d addr %d failed...!\n", port, addr);
		goto Exit;
	}
	switch(rbuf[len - 1]) {    // to identify equipment type
		/*
		 * xz2000 realtime data show
		 * */
		case 0:
			break;
		/*
		 * xz3000 realtime data show
		 * */
		case 1:
			break;
		/*
		 * xz3100 realtime data show
		 * */
		case 2:
			xz3100_data_show(rbuf, len);
			break;
		/*
		 * xz3500 realtime data show
		 * */
		case 3:
			break;
		/*
		 * xz6000 realtime data show
		 * */
		case 4:
			break;
	}
	printf("Do you want to refresh these equipment data...?Y/N:");
	getchar();
	ch = getchar();
	if(ch == 'Y' || ch == 'y') {
		goto Next;

	}
	else goto Exit;
Exit: 
	TCPConnectionClose(clientfd);
	return 0;
}
/*
 * to send equipment control paragram remotely
 * */
int controlDA660() {
	uint port, addr;
	int len;
	int i, j;
	int n;
	int try = 0;
	int choice;
	struct tm *ptm;
	time_t ts;
	printf("---- Welcome to use DA660 Equipment Control Tool ----\n");
	/*
	 * to initialize client
	 * */
	TCPClientInit(&clientfd);
	if(clientfd < 0) {
		perror("client socket created failed...!\n");
	}
	while(TCPClientConnect(clientfd, serveraddr, control_cmd_port)) {
		perror("client connected failed...!\n");
		try++;
		usleep(1e5);
		if(try > 5) {         // to try 5 times to connect
			perror("client connected failed...!\n");
			goto Exit;
		}
	}
	/*
	 * input port
	 * */
	printf("input the port:");
	if(scanf("%d", &port) != 1) {
		perror("input argument invalid...!\n");
		goto Exit;
	}
	if(port < 0 || port > 15) {
		perror("port should be 0 ~ 15...!\n");
		goto Exit;
	}
	/*
	 * input addr
	 * */
	printf("input the addr:");
	if(scanf("%d", &addr) != 1) {
		perror("input data error, system crash!\n");
		goto Exit;
	}
	if(addr < 0 || addr >= 257) {
		perror("port should be 0 to 256...!");
		goto Exit;
	}
	sbuf[0] = port;
	sbuf[1] = addr;
	/*
	 * operation UI
	 * */
next:
	printf("---- 0:reset, 1:reset and alarm, 2:start A, 3:start B, 4:stop, 5:broadcastly timing, 6:nonbroadcastly timing, 7:exit ----\n");
	printf("please input your choice:");
	if(scanf("%d", &choice) != 1) {
		perror("input argument invalid, Stop to run...!\n");
		goto Exit;
	}
	/*
	 * to check the user's choice
	 * */
	if(!(choice <= 7 && choice >= 0)) {
		perror("Sorry, you have made wrong choice...!\n");
		goto Exit;
	}
	switch(choice) {
		case 0:      // reset operation
			sbuf[2] = 0;
			len = TCPWrite(clientfd, sbuf, 3);
			if(len <= 0) {
				perror("Sorry, data have not been sent from client...!\n");
				goto Exit;
			}
			else printf("reset at port %d addr %d successfully...!\n", port, addr);
			break;
		case 1:
			sbuf[2] = 1;  // reset and alarm operation
			len = TCPWrite(clientfd, sbuf, 3);
			if(len <= 0) {
				perror("Sorry, data have not been sent from client...!\n");
				goto Exit;
			}
			else printf("reset and alarm at port %d addr %d successfully...!\n", port, addr);
			break;
		case 2:
			sbuf[2] = 2;  // start A operation
			len = TCPWrite(clientfd, sbuf, 3);
			if(len <= 0) {
				perror("Sorry, data have not been sent from client...!\n");
				goto Exit;
			}
			else printf("start A at port %d addr %d successfully...!\n", port, addr);
			break;
		case 3:
			sbuf[2] = 3;  // start B operation
			len = TCPWrite(clientfd, sbuf, 3);
			if(len <= 0) {
				perror("Sorry, data have not been sent from client...!\n");
				goto Exit;
			}
			else printf("start B at port %d addr %d successfully...!\n", port, addr);
			break;
		case 4:
			sbuf[2] = 4;  // stop operation
			len = TCPWrite(clientfd, sbuf, 3);
			if(len <= 0) {
				perror("Sorry, data have not been sent from client...!\n");
				goto Exit;
			}
			else printf("stop at port %d addr %d successfully...!\n", port, addr);
			break;
		case 5:           // broadcastly timing
			sbuf[2] = 5;
			time(&ts);
			ptm = localtime(&ts);
			sbuf[3] = (ptm->tm_year + 1900) / 100;
			sbuf[4] = (ptm->tm_year + 1900) % 100;
			sbuf[5] = ptm->tm_mon + 1;
			sbuf[6] = ptm->tm_mday;
			sbuf[7] = ptm->tm_hour;
			sbuf[8] = ptm->tm_min;
			sbuf[9] = ptm->tm_sec;
			len = TCPWrite(clientfd, sbuf, 10);
			if(len <= 0) {
				perror("Sorry, data have not been sent from client...!\n");
				goto Exit;
			}
			else printf("timing broadcastly at port %d successfully...!\n", port);
			break;
		case 6:          // nonbroadcastly timing       
			sbuf[2] = 6;
			time(&ts);
			ptm = localtime(&ts);
			sbuf[3] = (ptm->tm_year + 1900) / 100;
			sbuf[4] = (ptm->tm_year + 1900) % 100;
			sbuf[5] = ptm->tm_mon + 1;
			sbuf[6] = ptm->tm_mday;
			sbuf[7] = ptm->tm_hour;
			sbuf[8] = ptm->tm_min;
			sbuf[9] = ptm->tm_sec;
			len = TCPWrite(clientfd, sbuf, 10);
			if(len <= 0) {
				perror("Sorry, data have not been sent from client...!\n");
				goto Exit;
			}
			else printf("timing nonbroadcastly at port %d addr %d successfully...!\n", port, addr);
			break;
		case 7:
			goto Exit;
			break;
		}
	goto next;
Exit: 
	TCPConnectionClose(clientfd);
	return 0;
}
int main() {
	uchar choice;
	/*
	 * UI tips
	 * */
	printf("---- Welcome to DA660 Client System  Copyright 2014 ----\n");
	while(1) {
		printf("---- 0:Configure DA660, 1:Query real-time data, 2:Send control cmd, 3:Quit ----\n");
		printf("please input your choice:");
		if(scanf("%d", &choice) != 1) {
			perror("input argument invalid, Stop to run...!\n");
			goto Exit;
		}
		/*
		 * to check the user's choice
		 * */
		if(choice != 0 && choice != 1 && choice !=2 && choice != 3) {
			perror("Sorry, you have made wrong choice...!\n");
			char ch;
			printf("Continue or Quit...?Y/N: ");
			getchar();
			ch = getchar();
			if(ch == 'Y' || ch == 'y') continue;
			else goto Exit;
		}
		switch(choice) {
			case 0:
				configureDA660();  // Testing: It is OK!
				break;
			case 1:
				queryDA660();      // Testing: It is OK!
				break;
			case 2:
				controlDA660();     // Testing: It is OK!
				break;
			default:
				goto Exit;
				break;
		}
	}
Exit:
	printf("Thank you for your using, Good luck, Bye...!\n");

	return 0;
}

九、 测试

DA660端:


客户端:









十、编程要点

1. DA660有16个通道,采集数据必须写为16个线程,每个通道1个线程。

2. 报文构造尽量长,减少串口读写时间。