// serv.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include
#include
#include
#pragma comment (lib, "ws2_32.lib")
#include
#include
#pragma comment(lib,"Winmm.lib")
void ReiveData();
HANDLE hThreadHandle_page1;
DWORD dwThreadID_page1;
int fromlen;
int sendlen;
SOCKET socket1;
SOCKET socket2;
struct sockaddr_in client1;
struct sockaddr_in client2;
/*
仿真机与DCS双向发送的数据包格式相同,都由16字节的头部和最长1200字节的数据区构成。以下定义各字段字节数均按32位平台计算。
头部定义如下:
域号,unsigned char,仿真机向DPU发送数据时,是目标站的域号。如果目标站是全部DPU,填0xFF。当DPU向仿真机发送数据时,是源站(DPU)的域号。
站号,unsigned char,仿真机向DPU发送数据时,是目标站的站号。如果目标站是全部DPU,填0xFF。当DPU向仿真机发送数据时,是源站(DPU)的站号。
字节序标志,unsigned char,对于X86平台,等于1。
包类型,unsigned char,实时数据=128,命令=129,命令回应=130。
秒,unsigned long,代表数据发送时刻的数值(C函数time()的返回值)。
毫秒,unsigned short,数据发送时刻的毫秒部分。
CRC,unsigned short,数据区的CRC16校验值。
数据区长度,unsigned short,数据区的实际字节数(不含头部)。
数据包流水号,unsigned short,为过滤重复数据包,每包可给定不同的数字。
其中时间、CRC和数据包流水号可选。暂时可不处理这几项数据。
数据区是模拟量或开关量的实时数据,每个点占用8字节,两种数据可混合排放。每个点定义如下:
点ID,unsigned int,对照表规定了每个点的ID。
数值,float/int,由点ID确定点记录后,根据类型(模拟/开关)把数值部分的4字节解释为浮点数或整数。如果是开关点,整数是0或1。
根据以上定义,每个数据包最多容纳150个点记录的数据。
*/
typedef struct {
unsigned int ID;
char simbuff[4];
} DATAFIELD;
typedef struct
{
unsigned char domainname; //1byte 1
unsigned char stationid; //1byte 2
unsigned char byteflag; //1byte 3
unsigned char datatype; //1byte 4
unsigned long second; //4byte 8
unsigned short milsecond; //2byte 10
unsigned short CRC16; //2byte 12
unsigned short databyte; //2byte 14
unsigned short datanum; // 2byte 16 共16字节
DATAFIELD data[150];
}SIMDATA;
typedef struct
{
unsigned char domainname;
unsigned char stationid;
unsigned char byteflag;
unsigned char datatype;
unsigned long second;
unsigned short milsecond;
unsigned short CRC16;
unsigned short databyte;
unsigned short datanum;
int cmd; //命令
unsigned int parm1 ;//参数1
long parm2; //参数2
}CMDDATA;
/*
命令和参数定义如下:
命令 含义 参数1 参数2
1 运行/冻结 1运行,0冻结 忽略
2 抽点/回退 1回退,0抽点 组号
3 初始条件保存和加载 1保存条件,0加载条件 组号
4 抽点文件保存和加载 1保存,0加载 组号
5 删除所有抽点文件 忽略 忽略
6 删除所有初始条件 忽略 忽略
7 按参数判断删除那种文件
0:删除初始文件
1:删除抽点文件 仅当参数1等于0有效
-1:删除所有的初始文件
大于等于0的数字:要删除的初始文件组号。
*/
typedef struct
{
unsigned char domainname;
unsigned char stationid;
unsigned char byteflag;
unsigned char datatype;
unsigned long second;
unsigned short milsecond;
unsigned short CRC16;
unsigned short databyte;
unsigned short datanum;
int cmd ;
int error;
}CMDDATA_DCS;
/*
数值 含义
0 成功
1 指令或参数无效
2 指定文件不存在
3 访问指定文件出错(无访问权限,文件内容错误等)
*/
//SIMDATA simdata;
//CMDDATA_DCS simcmd;
int o_num ;
int i_num ;
int ao_num ;
int do_num ;
int di_num ;
int ai_num ;
#define REAL 1
#define FLOAT 2
#define LONG 3
#define SHORT 4
#define INT 5
#define LOG 6
#define DOUBLE 7
#define DOUBLE2 8
#define S3_VARLEN 48
typedef union {
double r8;
float r4;
int i4;
double i8;
short i2;
char i1;
} VAL;/*from s3_parm.h variable value*/
typedef char VAR[S3_VARLEN] ; /*variable name*/
typedef struct
{
VAR varname;
int index;
char *vaddress;
VAL oldvarvalue;
char type1; //r,i,
char type2; //r,i,
char vartype;
}DATA;
typedef struct
{
int index; /* the order of variable in the picture*/
char vartype;
VAL varvalue;
}getdata;
#define AO 1
#define DO 2
#define AI 3
#define DI 4
#define pr
#define MAXIN 10240
#define MAXOUT 20480//10240
#define INLEN 16*MAXIN+8
#define OUTLEN 16*MAXOUT+8
DATA data_i[MAXIN];
DATA data_o[MAXOUT];
getdata val_i[MAXIN];
getdata val_o[MAXOUT];
float fgsevalue[MAXOUT];
int igsevalue[MAXOUT];
//
float global_floatdata[100];
float sim_data[150];
unsigned char simbuff[1216];
char m_buffer[1216];
char send_buffer[28];
char simbuff_cmd[28];
char cmd_buffer[28];
int all_data_count;
int count150;
SIMDATA simdata;
CMDDATA simcmd;
#define DATA_RECEIVE_LEN 1216 //数据包
char rev_buffer[DATA_RECEIVE_LEN];
unsigned char rev_data[DATA_RECEIVE_LEN];
unsigned char revbuff[DATA_RECEIVE_LEN];
float global_revdata[100];
int cmd;
unsigned int parm1;
long parm2;
SIMDATA revdata;
CMDDATA_DCS revcmd;
int InitSocket(); //初始化套接字
void SendParametorDataByTimer( ); //发送参数信息,以一定时间间隔,如0.1秒或1秒等
void SendCommandDataChange( ); //发送命令信息,当命令字发生变化
void buildData_Head(); //建立数据头数据
void buildData_CMDHead(); //建立命令头数据
void GetRealValue(); //获取实时值
void ReceiveCommandDataChange( ); //接收DCS命令信息,当命令字发生变化
void buildData_Head() //建立数据头数据
{
simdata.domainname = 0xFF;
simdata.stationid = 0xFF;
simdata.byteflag = 1;
simdata.datatype = 128;
simdata.second = 128;
simdata.milsecond = 1;
simdata.CRC16 = 0;
simdata.databyte =1200;
simdata.datanum = 0;
}
void buildData_CMDHead() //建立命令头数据
{
simcmd.domainname = 0xFF;
simcmd.stationid = 0xFF;
simcmd.byteflag = 1;
simcmd.datatype = 129;
simcmd.second = 128;
simcmd.milsecond = 1;
simcmd.CRC16 = 0;
simcmd.databyte =12;
simcmd.datanum = 0;
}
/************************************************************************************************************
GetAddrFromDBM
*************************************************************************************************************/
void GetRealValue() //获取实时值
{
int ista,i,j;
// for( i=0;i
//memcpy(&fgsevalue[i],data_o[i].vaddress+4*i,4);
fgsevalue[i] = i*10.;
//printf("fgsevalue %f i= %d \n", fgsevalue[i], i );
}
printf("finished get real time value.\n");
}
void ReiveData()
{
int i;
float gsedata[150];
while (1)
{
printf("waiting for message from others-------------\n");
if (recvfrom(socket1,rev_buffer,sizeof(rev_buffer),0,(struct sockaddr*)&client1,&sendlen)!=SOCKET_ERROR)
{
memcpy(&revbuff,rev_buffer,sizeof(rev_buffer));
memcpy(&revdata.domainname, &revbuff[0], sizeof(char));
memcpy(&revdata.stationid, &revbuff[1], sizeof(char));
memcpy(&revdata.byteflag, &revbuff[2], sizeof(char));
memcpy(&revdata.datatype, &revbuff[3], sizeof(char));
memcpy(&revdata.second, &revbuff[4], 4*sizeof(char));
memcpy(&revdata.milsecond, &revbuff[8], 2*sizeof(char));
memcpy(&revdata.CRC16, &revbuff[10], 2*sizeof(char));
memcpy(&revdata.databyte, &revbuff[12], 2*sizeof(char));
memcpy(&revdata.datanum, &revbuff[14], 2*sizeof(char));
printf("%d simdata.databyte \n",revdata.databyte);
int value = revdata.databyte;
if(value == 1200){
memcpy(&revdata.data, &revbuff[16], 1200*sizeof(char));
for (i = 0;i<150;i++)
{
memcpy( &gsedata[i] ,&revdata.data[i].simbuff, 4*sizeof(char) );
// printf( "gsedata i = %d value = %f \n",i, gsedata[i]);
}
// printf("%x revdata.domainname \n",revdata.domainname);
// printf("%x revdata.stationid \n",revdata.stationid);
// printf("%x revdata.byteflag \n",revdata.byteflag);
// printf("%x revdata.datatype \n",revdata.datatype);
// printf("%d revdata.second \n",revdata.second);
printf("%d simdata.databyte \n",revdata.databyte);
printf("%d simdata.datanum \n",revdata.datanum);
printf("--------------------------------\n");
// printf("revdata.data.ID %d \n",revdata.data[0].ID);
// printf("revdata.data.simbuff %f \n",revdata.data[0].simbuff);
// printf("revdata.data.ID %d \n",revdata.data[2].ID);
// printf("revdata.data.simbuff %f \n",revdata.data[2].simbuff);
}
else if ( value == 12){
memcpy(&cmd, &revbuff[16], 4*sizeof(char));
memcpy(&parm1, &revbuff[20], 4*sizeof(char));
memcpy(&parm2, &revbuff[24], 4*sizeof(char));
printf("cmd ****** %d \n",cmd);
printf("parm1 ****** %d \n",parm1);
printf("parm2 ****** %d \n",parm2);
}
}
}
closesocket(socket1);
}
void SendParametorDataByTimer( ) //发送参数信息,以一定时间间隔,如0.1秒或1秒等
{ int i,j;
bool m_nThreadStatus = true;
memset(m_buffer, 0, sizeof(m_buffer));
all_data_count = 1500;
//while( m_nThreadStatus )
{
GetRealValue(); //获取实时运行数据
/***************************仿真数据包********************/
buildData_Head();//封装数据包头
//all_data_count = ao_num+do_num;
//仿真数据
if( all_data_count< 150)
{
for (i=0;i
simdata.data[i].ID = data_o[i].index;
sim_data[i] = fgsevalue[i];
memcpy( simdata.data[i].simbuff,&sim_data[i],4*sizeof(char));
}
for (i=all_data_count;i<150;i++) //填充无用数据
{
simdata.data[i].ID = 200000;
sim_data[i] = 0;
memcpy( simdata.data[i].simbuff,&sim_data[i],4*sizeof(char));
}
memcpy(simbuff, &simdata, sizeof(SIMDATA));
memcpy(m_buffer,simbuff,sizeof(simbuff));
if( sendto(socket1,m_buffer,sizeof(m_buffer),0,(struct sockaddr*)&client2,sendlen)!=SOCKET_ERROR)
{
printf("sending data successly ..\n");
}
}
//>150或者为其整数倍
count150 = (int)(all_data_count/150.);
for(j = 0;j< count150;j++)
{
simdata.datanum = j+1;
for (i=0;i<150;i++)
{
simdata.data[i].ID = data_o[i+j*150].index;
sim_data[i] = fgsevalue[i+j*150];
memcpy( simdata.data[i].simbuff,&sim_data[i],4*sizeof(char));
}
simcmd.datanum = j+1;
memcpy(simbuff, &simdata, sizeof(SIMDATA));
memcpy(m_buffer,simbuff,sizeof(simbuff));
if( sendto(socket1,m_buffer,sizeof(m_buffer),0,(struct sockaddr*)&client2,sendlen)!=SOCKET_ERROR)
{
printf("sending data successly ..\n");
}
}
//Sleep(1000);
}
//closesocket (socket2);
}
void SendCommandDataChange( ) //发送命令信息,当命令字发生变化
{
int i;
bool m_nThreadStatus = true;
//memset(cmd_buffer, 0, sizeof(cmd_buffer));
//while( m_nThreadStatus )
{
/*命令数据包*/
buildData_CMDHead();
simcmd.cmd = 1;
simcmd.parm1 = 1;
simcmd.parm2 = 0;
if(simcmd.datanum == 0 )
simcmd.datanum = 1;
else
simcmd.datanum = 0;
memcpy(simbuff_cmd, &simcmd, sizeof(CMDDATA));
memcpy(cmd_buffer,simbuff_cmd,sizeof(simbuff_cmd));
if( sendto(socket2,cmd_buffer,sizeof(cmd_buffer),0,(struct sockaddr*)&client2,sendlen)!=SOCKET_ERROR)
{
printf("sending data successly ..\n");
}
//Sleep(1000);
}
//closesocket (socket2);
}
// add by ch
const int MAX_KEY_NUM = 128;
const int MAX_KEY_LENGTH = 1024;
char gKeys[MAX_KEY_NUM][MAX_KEY_LENGTH];
char *GetIniKeyString(char *title, char *key, char *filename)
{
FILE *fp;
int flag = 0;
char sTitle[32], *wTmp;
char sLine[MAX_KEY_LENGTH];
sprintf(sTitle, "[%s]", title);
if (NULL == (fp = fopen(filename, "r")))
{
perror("fopen");
return NULL;
}
while (NULL != fgets(sLine, MAX_KEY_LENGTH, fp))
{
/// 这是注释行 ///
if (0 == strncmp("//", sLine, 2)) continue;
if ('#' == sLine[0]) continue;
wTmp = strchr(sLine, '=');
if ((NULL != wTmp) && (1 == flag))
{
if (0 == strncmp(key, sLine, wTmp - sLine)) /// 长度依文件读取的为准 ///
{
sLine[strlen(sLine) - 1] = '\0';
fclose(fp);
return wTmp + 1;
}
}
else
{
if (0 == strncmp(sTitle, sLine, strlen(sLine) - 1)) /// 长度依文件读取的为准 ///
{
flag = 1; /// 找到标题位置 ///
}
}
}
fclose(fp);
return NULL;
}
void WINAPI onTimeCommand(UINT wTimerID, UINT msg,DWORD dwUser,DWORD dwl,DWORD dw2);
void WINAPI onTimeCommand(UINT wTimerID, UINT msg,DWORD dwUser,DWORD dwl,DWORD dw2)
{
printf("onTimeCommand do ...\n");
SendCommandDataChange();
return;
}
void WINAPI onTimePara(UINT wTimerID, UINT msg,DWORD dwUser,DWORD dwl,DWORD dw2);
void WINAPI onTimePara(UINT wTimerID, UINT msg,DWORD dwUser,DWORD dwl,DWORD dw2)
{
printf("onTimePara do ...\n");
SendParametorDataByTimer();
return;
}
//开启2个定时器
void startTimer()
{
char * timeCommand = (char*)malloc(100 * sizeof(char));
strcpy(timeCommand,GetIniKeyString("Timer", "timeCommand", "config.ini"));
printf("timeCommand is %s\n", timeCommand);
MMRESULT timer_command;
timer_command = timeSetEvent(atoi(timeCommand), 1, (LPTIMECALLBACK)onTimeCommand, DWORD(1), TIME_PERIODIC);
if(NULL == timer_command)
{
printf("timeSetEvent()timer_command failed with error %d/n", GetLastError());
return ;
}
char * timePara = (char*)malloc(100 * sizeof(char));
strcpy(timePara,GetIniKeyString("Timer", "timePara", "config.ini"));
printf("timePara is %s\n", timePara);
MMRESULT timer_para;
timer_para = timeSetEvent(atoi(timePara), 1, (LPTIMECALLBACK)onTimePara, DWORD(1), TIME_PERIODIC);
if(NULL == timer_para)
{
printf("timeSetEvent() timer_para failed with error %d/n", GetLastError());
return ;
}
}
// add by ch
int _tmain(int argc, _TCHAR* argv[])
{
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2,1),&wsaData)) //调用Windows Sockets DLL
{
printf("Winsock无法初始化!\n");
WSACleanup();
return 0;
}
printf("服务器开始创建SOCKET。\n");
//读取配置文件开始
char * ipOne = (char*)malloc(100 * sizeof(char));
strcpy(ipOne,GetIniKeyString("IPSite", "socketOneIp", "config.ini"));
printf("ipOne is %s\n", ipOne);
char * portOne = (char*)malloc(100 * sizeof(char));
strcpy(portOne,GetIniKeyString("IPSite", "socketOnePort", "config.ini"));
printf("portOne is %s\n", portOne);
char * ipTwo = (char*)malloc(100 * sizeof(char));
strcpy(ipTwo,GetIniKeyString("IPSite", "socketTwoIp", "config.ini"));
printf("ipTwo is %s\n", ipTwo);
char * portTwo = (char*)malloc(100 * sizeof(char));
strcpy(portTwo,GetIniKeyString("IPSite", "socketTwoPort", "config.ini"));
printf("portTwo is %s\n", portTwo);
//读取配置文件结束
fromlen =sizeof(client1);
client1.sin_family=AF_INET;
client1.sin_port=htons(atoi(portOne)); ///监听端口
client1.sin_addr.s_addr=inet_addr(ipOne); ///server的地址
socket1=socket(AF_INET,SOCK_DGRAM,0);
bind(socket1,(struct sockaddr*)&client1,sizeof(client1));
sendlen =sizeof(client2);
client2.sin_family=AF_INET;
client2.sin_port=htons(atoi(portTwo)); ///监听端口
client2.sin_addr.s_addr=inet_addr(ipTwo); ///server的地址
socket2=socket(AF_INET,SOCK_DGRAM,0);
//bind(socket2,(struct sockaddr*)&client2,sizeof(client2));
startTimer(); // add by ch
// ReiveData();
SendParametorDataByTimer( );
//SendCommandDataChange( );
return 0;
}