资讯详情

udp server 2013-10-26

#include "stdio.h" #include <stdlib.h>

#define NET_PACKET_DATA_SIZE 1024 //估计一包的大小暂时为1k #define NET_PACKET_SIZE (sizeof(NetPacketHeader) NET_PACKET_DATA_SIZE) * 100

typedef struct { unsigned char data[NET_PACKET_DATA_SIZE]; //format sockaddr_in cliaddrIP udp packet

}One_RecvdPacket; //一包数据

typedef struct { char data[NET_PACKET_DATA_SIZE];//format sockaddr_in cliaddrIP bool crcresult const unsigned char* pDataBuffer, unsigned short nDataSize,

}One_SendPacket; //一包数据

typedef struct { char data[NET_PACKET_DATA_SIZE];

}One_InsertSql; //write sql text

/ 网络数据包包头 //struct NetPacketHeader //{ //unsigned shortwDataSize;///< 数据包的大小包括封包头和封包数据 //unsigned shortwOpcode;///< 操作码 //}; // / 网络数据包 //struct NetPacket //{ //NetPacketHeaderHeader;///< 包头 //unsigned charData[NET_PACKET_DATA_SIZE];///< 数据 //}; //typedef struct //{ //}B;

/// 网络数据包包头 typedef struct ///物理链路1Bytes协议版本1Bytes帧长2Bytes { unsigned char net_type; unsigned char doc_ver; char UDID[6]; char crcres[4]; unsigned short frame_datalen; }NetPacketHeader;

/// 网络数据包 typedef struct { NetPacketHeaderHeader;///< 包头 unsigned char Data[NET_PACKET_DATA_SIZE];///< 业务数据区 }NetPacket;

//

/// 网络操作码 enum eNetOpcode { NET_TEST1 = 1, CMD_NET_HEARTBEAT = 0x0010, //心跳数据 CMD_NET_LOGIN = 0x0012, //2.3.2终端登录请求-0X0012 CMD_NET_EXP_LOGIN = 0x0013, //2.3.3终端异常登录请求-0X0013 CMD_NET_DEVICEID_INFO = 0x0015, //2.3.4终端器件ID信息数据-0X0015 CMD_NET_STATUS_REPORT = 0x0017, //2.3.5终端待机请求/状态报告-0X0017 CMD_NET_WEB_INFO = 0x0019,//2.3.6终端车辆设备网络接口信息-0X0019 CMD_NET_SENSOR_DATA = 0x0020,//2.3.7终端传感器数据-0X0020 CMD_NET_GPS_DATA = 0x0022,//2.3.8终端定位数据-0X0022 CMD_NET_DIAGNOSIS_DATA = 0x0030, //诊断数据 }; enum eGPSway 定位方式:1 字节,0x01 = GPS标准定位,0x02 = GPS精简定位,0x05 = 基站定位。 { GPS_STRDAND =0x01, GPS_SIMPLE =0x02, GPS_BASE =0x05, }; /// 测试1的网络数据包定义 //struct NetPacket_Test1 //{ //intnIndex; //chararrMessage[512]; //}; typedef struct //DPU_String :<长度字节> <字符串> { unsigned short uLen;///双字节数字,指定字符串长度(包括\0’字符)。 char data;///业务数据内容1字节 }Heart_Beat;

typedef struct //DPU_String :<长度字节> <字符串> { unsigned short uLen;///双字节数字,指定字符串长度(包括\0’字符)。 char data[512]//字符串 }DPU_String;

// struct DPU_String //DPU_String :<长度字节> <字符串> // { // unsigned short uLen;///双字节数字,指定字符串长度(包括\0’字符)。 // char * pdata;//字符串,可变数组的大小 // // DPU_String():uLen(0),pdata(NULL) // { // // } // ~DPU_String() // { // if (pdata!=NULL) // { // free(pdata); // printf("~DPU_String memory release\n");//char *Ptr = NULL; Ptr = (char *)malloc(100 * sizeof(char)); // code... free(Ptr); Ptr // &bsp; } //  } // }; //以下每一条业务serviceID对应一个结构体,整个业务数据包对应一条RCU 数据记录,也有一个相应结构体

typedef struct {

 DPU_String  Device_type;  DPU_String  Hardware_ver;  DPU_String  Software_ver;  DPU_String  Car_language;  DPU_String  Car_name;  DPU_String  Car_ver;  char  Vendor_name[12];  char  Device_serial[12];  char  Device_IMEI[15];  char  SIM_num[20];  char  Crypt_txt[32];

}Struct_Login_Info;

typedef struct {  DPU_String  Device_type;  char  Device_serial[12];  char  Device_IMEI[15];  char  SIM_num[20];  char  Crypt_txt[32];

}Exp_Login;

typedef struct {  char vin_code[17];      //0X0300  unsigned short    carspeed;   //0X0301 车速  unsigned short    motorspeed;  //0X0302 发动机转速  float             cur_oilwear;//0X0303 瞬时油耗

 float             avg_oilwear;//0X0304 平均油耗  unsigned char     key_info;    //0X0305 钥匙信息 1 U8    float       mileage_fault;    // 0X030E 带故障行驶里程 4 float km     unsigned int      cur_mileage ;  //0X0310 当前里程  float             oil_temperature;  //0X0311 油温 4 float

 unsigned char     oil_remain;    //0X0312 剩余油量 1 U8 %

 unsigned int      mileage_remain;  //0X0313 剩余里程   unsigned short    journey_count; // 旅程次数 2 U16  unsigned short    fire_count;  //点火次数 2 U16

  float             air_pressure;   // 0X0314 大气压 4 float   float             carout_temperature;  //0X0316 车外温度 4 float   float             carin_temperature;// 0X0317 车内温度 4 float     unsigned int   MIL_infolight;     //0X0319 MIL 信号灯 4 U8   float             left_front_tire_press;  //0X0320 左前轮胎压 4 float   float             left_back_tire_press;  // 0X0321 左后轮胎压 4 float     float             right_front_tire_press;  //0X0322 左前轮胎压 4 float   float             right_back_tire_press;  //0X0323 左前轮胎压 4 float

    unsigned short    gasbag_info;       //0X03A0 气囊信息   unsigned short    seatbelt_info;       //  0X03A1 安全带信息   unsigned short    car_door_info;            //0X03A2 车门信息 2 U16   unsigned short    car_win_info;             //0X03A3 车窗信息 2 U16   unsigned char     turn_light_info;                //0X03A4 方向灯信息 1 U8     unsigned char     brake_info;            //0X03B2 刹车信息 1 U8   unsigned char     gear_info;         //0X03DA 挡位信息                  // 支持PIDs 可变可多包发送               // 读故障码 可变可多包发送                 }Diagnosis_Data;

typedef struct {    //<date>,<time>,<lat>,<long>,<alt>,<uncertainty>  char date[20];  char time[20];  char lat_info[20];  char long_info[20];  int  alt_info;  int  uncertainty;     }GPS_DataBase;

typedef struct {

 unsigned short timezone;  // 619 timezone  unsigned short ms;  unsigned short year;  unsigned short month;  unsigned short day;  unsigned short hour;  unsigned short minute;  unsigned short sencond;

}Timestamp;

//GPS 位置信息数据长度不定,格式为: // <UTC 时间>,<定位有效性>,<纬度>,<北纬或南纬>,<经度>,<东经或西经>,<速度>,<方位角>,<UTC 日期>,<GPS 状态>,<.HDOP>,<海拔高度>,<定位模式> ,<有效卫星个数> // // 解释: // UTC 时间为6-10 字节,UTC 时间,hhmmss.XXX(时分秒.毫秒)格式;(GPRMC 数据)。 // 定位有效性为1 字节,A=有效定位,V=无效定位(GPRMC 数据)。 // 纬度一般为9 字节,格式为:2232.1234,22 为度,32.1234 为分(GPRMC 数据)。ddmm.mmmm // 北纬或南纬为一字节,N 或S(GPRMC 数据)。 // 经度一般为10 字节,格式为11345.1234,113 为度,45.1234 为分(GPRMC 数据)。dddmm.mmmm // 东京或西经为1 字节,E 或W(GPRMC 数据)。 // 速度为浮点数,单位为海里,000.0~999.9 节,前面的0 也将被传输(GPRMC 数据)。 // 方位角为浮点数,范围000.0~359.9 度,以正北为基准,前面的0 也将被传输(GPRMC 数据)。 // UTC 日期为6 字节,ddmmyy(日月年)格式 (GPRMC 数据)。 // GPS 状态为1 字节,0=未定位,1=非差分定位,2=差分定位,6=正在估算(GPGGA 数据)。 // 有效卫星个数,可见讯号的卫星的总数,00 至 12(GPGSV 数据)。 // 海拔高度,单位为米,范围为-9999.9~99999.9,(GPGGA 数据)。 // HDOP,水平精度因子,范围0.5~99.9,数字越大表明误差越大,99.9 表明未定位(GPGGA 数据)。 // 定位模式1 字节,1 = 未定位, 2 = 二维定位, 3 = 三维定位。(GPGSA 数据)

typedef struct {

 //<date>,<time>,<lat>,<long>,<alt>,<uncertainty>  unsigned short     UTC_time[4];   //UTC_time[0] UTC_time[1] UTC_time[2]时UTC_time[3]分秒.毫秒  char    posvalid;     //定位有效性  float   weidu[2];       //纬度 weidu[0]度/ weidu[1]分  char     beiwei;  float   jingdu[2];   //经度 jingdu[0]度/ jingdu[1]分  char    dongjing;    //东经或西经  float   speed;  float   direction_angle;  int     UTC_date[3];  //day/month/year    UTC_date[0]  UTC_date[1]  UTC_date[2]    char GPS_status;   //GPS 状态为1 字节,0=未定位,1=非差分定位,2=差分定位,6=正在估算(GPGGA 数据)。     float   HDOP ;  float   high;  char posmodel;   //定位模式1 字节,1 = 未定位, 2 = 二维定位, 3 = 三维定位  unsigned short star_num;   //有效卫星个数,可见讯号的卫星的总数,00 至 12(GPGSV 数据)。

}GPS_DataStandard;

 

/.cpp

#include<stdio.h> #include<stdlib.h> #include<string.h> #include<unistd.h> #include<sys/socket.h> #include<netinet/in.h> #include<pthread.h> #include<arpa/inet.h> #include<sys/types.h> #include<sys/time.h> #include<errno.h>

#include <stdbool.h> #include "NetDefine.h" #include "/usr/include/mysql/mysql.h"

extern "C"   //c文件与c++文件混合编程 {    #include "crc.h"   }

#include <list> using namespace std;

#define BUFFSIZE 1024 #define PORT 9100 #define BACKLOG 5 #define MAXFD 5

 

 

list<One_InsertSql> g_recordlist_write_SQL;//list<Struct_Login_Info> g_recordlist_write_SQL;//暂时指登陆信息,之后是指写入数据库的一条记录,来自设备的整包业务数据

list<One_RecvdPacket>   g_ReceviedDataList; list<One_SendPacket>    g_readySendDataList;

pthread_mutex_t     mutex_logininfo=PTHREAD_MUTEX_INITIALIZER;//CRITICAL_SECTION g_cs_logininfo ; pthread_mutex_t     g_mutex_recevieddata=PTHREAD_MUTEX_INITIALIZER;//CRITICAL_SECTION g_cs_logininfo ; pthread_mutex_t     g_mutex_senddata=PTHREAD_MUTEX_INITIALIZER;//CRITICAL_SECTION

 

//list<int> g_list2; MYSQL *mysql_conn; int   g_server_sock;

void    doClientRequest(int server_sock); void *  doClientThread(void *pParam); void    OnServiceData(sockaddr_in  cliaddrIP ,const unsigned  char* pDataBuffer, unsigned short nDataSize ); bool    OnServiceIDMessage( long long udid,const unsigned short nOpcode,const unsigned char* pDataBuffer, unsigned short nDataSize ) ; // by yand void    ToHex( char * src, int length, char * dst ); void    get_client_IP(int clientsock); unsigned short TwoByte2short(char *p); void    put_record(One_InsertSql writesql); //写一条数据到链表 bool    get_record(One_InsertSql * writesql);   //从链表读取一条数据写入数据库

bool    CrcCheckData(const unsigned char* pDataBuffer, unsigned short nDataSize); Timestamp get_timestamp(unsigned char *pdata,int len ); unsigned char Find_char_add_len(unsigned char *indata,int *gps_datalen,unsigned char *gprs_straddr[]); uint32_t gprs_data_crc32(uint8_t * indata,uint16_t len);

void    mysql_connect(); void    mysql_disconnect(); void *  WriteMysqlThread(void *pParam) ; void *  HandleDataThread(void *pParam) ; void *  SendtoRCUThread(void *pParam) ;     void mysql_connect() {    char *server = "192.168.16.111";   //"127.0.0.1";  //192.168.78.130//"localhost";    char *user = "yandong"; //root    char *password = "123456"; //"mysql"; /* 此处改成你的密码 */    char *database = "test";    mysql_conn = mysql_init(NULL);    /* Connect to database */    //if (mysql_real_connect(conn, server,user, password, database, 0, NULL, 0)){  //localhost port=0    if (mysql_real_connect(mysql_conn, server,user, password, database, 0, NULL, 0))    {            printf("mysql success connect\n");    }     } void mysql_disconnect() {     mysql_close(mysql_conn);      }    void *WriteMysqlThread(void *pParam)  //独立数据库写线程 {   int temp=(int)pParam;   MYSQL_RES *res;   MYSQL_ROW row;   while(1)   {      One_InsertSql onesql;      bool bres=get_record(&onesql);           if (true == bres)//取得记录了      {       /* send SQL query */       char chsql[1000]; //        char  Vendor_name[12+1]; //        char  Device_serial[12+1]; //        char  Device_IMEI[15+1]; //        char  SIM_num[20+1]; //        char  Crypt_txt[32+1];//最后一个字节默认初始就是'\0' //        memset(Vendor_name,0,sizeof(Vendor_name)); //        memset(Device_serial,0,sizeof(Device_serial)); //        memset(Device_IMEI,0,sizeof(Device_IMEI)); //        memset(SIM_num,0,sizeof(SIM_num)); //        memset(Crypt_txt,0,sizeof(Crypt_txt)); //        memcpy(Vendor_name,lf.Vendor_name,sizeof(lf.Vendor_name)); //        memcpy(Device_serial,lf.Device_serial,sizeof(lf.Device_serial)); //        memcpy(Device_IMEI,lf.Device_IMEI,sizeof(lf.Device_IMEI)); //        memcpy(SIM_num,lf.SIM_num,sizeof(lf.SIM_num)); //        memcpy(Crypt_txt,lf.Crypt_txt,sizeof(lf.Crypt_txt)); //       sprintf(chsql,"insert into login_info (device_type,hardware_ver,software_ver,car_lan,car_name,car_ver,vendor_name, \ //       dev_serial,dev_IMEI,SIM_num,cry_txt) \ //       values ('%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s')",lf.Device_type.data,lf.Hardware_ver.data,lf.Software_ver.data, \ //       lf.Car_language.data,lf.Car_name.data,lf.Car_ver.data, \ //       Vendor_name, Device_serial,Device_IMEI,SIM_num,Crypt_txt); //       printf("chsql:%d,%s\n",strlen(chsql),chsql);

      if ( mysql_query(mysql_conn, onesql.data) ) {        fprintf(stderr, "insert :%s\n", mysql_error(mysql_conn));        return NULL;       }       else       {        printf("insert success rows:%lu\n",(ulong)mysql_affected_rows(mysql_conn));       }

//        res=mysql_use_result(mysql_conn); //        printf("MySQL Tables in mysql databases:\n"); //        while((row=mysql_fetch_row(res))!=NULL) //         printf("%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s \n",row[0],row[1],row[2],row[3],row[4],row[5],row[6],row[7],row[8],row[9],row[10]);

//      }      //sleep(1); //停留1秒      usleep(1000*100); //停留1秒 ,这里是设置写记录数据库的频率,如果慢把时间设置减少      /* send SQL query */             }

}

 

 

void put_record(One_InsertSql writesql)//(Struct_Login_Info login_info) {    //Lock(cs);  pthread_mutex_lock(&mutex_logininfo);          g_recordlist_write_SQL.push_back(writesql);         pthread_mutex_unlock(&mutex_logininfo);  //unLock(cs); } bool get_record(One_InsertSql * writesql) {  bool bres=false;

 pthread_mutex_lock(&mutex_logininfo); //Lock(cs);      // if (g_recordlist_write_SQL.size() <=0) //没记录    // {    //      //   bres=false;    //   //return bres;//别在这返回,最后解然后返回,别忘解锁pthread_mutex_unlock    // }

    for (list<One_InsertSql>::iterator it = g_recordlist_write_SQL.begin(); it != g_recordlist_write_SQL.end(); ++it)      {       One_InsertSql InsertSql=*it;      memcpy(writesql,&InsertSql,sizeof(One_InsertSql));       bres=true;       break;//只取前面第一条      }    if(true == bres )    {         g_recordlist_write_SQL.pop_front(); //从链表头取出一条后,杀掉这条    }      pthread_mutex_unlock(&mutex_logininfo);  //unLock(cs);    return bres; }

// 输出一个链表 //void ShowList(list<int>& listTemp) //{  //  //  size()返回链表中元素个数    //  cout << listTemp.size() << endl;    //  for (list<int>::iterator it = listTemp.begin(); it != listTemp.end(); ++it)    //   {       //     cout << *it << ' ';   //   }    //   cout << endl; //}

int main(void) {     int server_sock,client_sock,result,len,para;     struct sockaddr_in serveraddr;     pthread_t pt;  

   if((server_sock=socket(AF_INET,SOCK_DGRAM,0))<0)  //udp         {                 perror("server socket:");                 exit(-1);         }    g_server_sock = server_sock;

   puts("server socket is OK!");    bzero(&serveraddr,sizeof(serveraddr));    serveraddr.sin_family=AF_INET;    serveraddr.sin_addr.s_addr=htonl(INADDR_ANY);    serveraddr.sin_port=htons(PORT);                 len=sizeof(serveraddr);   

   int opt = 1;    setsockopt(server_sock,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt)); //address already in use problem    if((result=bind(server_sock,(struct sockaddr*)&serveraddr,sizeof(serveraddr)))<0)         {                         perror("server bind:");                         exit(-1);         }    printf("server bind is OK!server_sock:%d \n",server_sock);

   all below threads//

//  below is recv data thread//                           if((result=pthread_create(&pt,NULL,doClientThread,(void *)&server_sock))!=0) //recv all udp data thread     {             perror("pthread recv data create fail:\n");             exit(-1);     }else  {             printf("recv data thread create success.....\n");  }     //below is handle data thread  if((result=pthread_create(&pt,NULL,HandleDataThread,(void *)&server_sock))!=0) //handle all udp data thread  {   perror("pthread handle data create fail:\n");   exit(-1);  }else  {   printf("handle data thread create success.....\n");  }

 //below is mysql write udp data thread  pthread_t pwsql;  mysql_connect();//sql init and connect  if((result=pthread_create(&pwsql,NULL,WriteMysqlThread,NULL ) )!=0)   //独立写mysql数据库线程  {   perror("pthread WriteMysqlThread create fail:");   exit(-1);  }else  {

  printf("mysql thread create success.....\n");  }     /below is send respose udp packet to RCU thread/

 //void * SendtoRCUThread(void *pParam)  if((result=pthread_create(&pt,NULL,SendtoRCUThread,(void *)&server_sock))!=0) //handle all udp data thread  {   perror("pthread SendtoRCUThread create fail:\n");   exit(-1);  }else  {   printf(" SendtoRCUThread create success.....\n");  }

 //

 while (1) // main thread  {   sleep(1); // sleep 1 s  }

//                         printf("%d create thread ok\n",client_sock); //                         //char ip[20]; //                         printf("connect "); //                         get_client_IP(client_sock);//print the client IP //                         //printf("connect client IP:%s\n",ip); //                 } //                 exit(0); }

void * HandleDataThread(void *pParam)  //handle service data thread when the list data buffer is not null {

 while(1)  {                     usleep(1000); // 1ms

     bool bget=false;

     One_RecvdPacket recvpacket;

     pthread_mutex_lock(&g_mutex_recevieddata); //Lock(cs);  //get one record data from list buffer queue

      for (list<One_RecvdPacket>::iterator it = g_ReceviedDataList.begin(); it != g_ReceviedDataList.end(); ++it)       {        recvpacket=*it;        //memcpy(plogin_info,&recvpacket,sizeof(One_RecvdPacket));        bget=true;        break;//只取前面第一条       }       if(true == bget )       {        g_ReceviedDataList.pop_front(); //从链表头取出一条后,杀掉这条       }

     pthread_mutex_unlock(&g_mutex_recevieddata);

   if (false == bget) // if g_ReceviedDataList size is null , so can't get data    {     //printf("can't get one record data from g_ReceviedDataList.......\n");     continue;

   }else // handle data part             {

        struct sockaddr_in  cliaddr;

                          memcpy(&cliaddr,recvpacket.data,sizeof(cliaddr));

     unsigned char *udpdata=recvpacket.data+sizeof(cliaddr);      NetPacketHeader* pHead = (NetPacketHeader*) (udpdata);

     unsigned char *pdata=udpdata;      //printf pHead      printf("net_type:%c,doc_ver:%c,frame_datalen:%d\n",pHead->net_type,pHead->doc_ver,pHead->frame_datalen);      //struct NetPacketHeader  //物理链路1Bytes 协议版本1Bytes 帧长2Bytes

     const unsigned short nPacketSize = sizeof(NetPacketHeader)+pHead->frame_datalen;    //整个完整一包数据大小,包含包头      //const unsigned short nDataSize = nPacketSize - (unsigned short)sizeof(NetPacketHeader); //      printf("data start....\n\n\n"); //      printf("nPacketSize:%d \n",nPacketSize); //      for(int i=0;i<nPacketSize;i++) //      { //       printf("%x ",*pdata++); //       if(i%16==0) //       { //        printf("\n"); //       } //      } //      printf("\n"); //      exit(0);

     //struct sockaddr_in servaddr, cliaddr;      OnServiceData(cliaddr,pdata, nPacketSize);  //nDatasize  

   }

 

 }

 

} void doClientRequest(int server_sock)  //recv data thread {

 int nRecvsize=0;  socklen_t len;  unsigned char mesg[NET_PACKET_SIZE];  //struct sockaddr_in *pcliaddr;//segmentaion fault ---null point problems  socklen_t clilen;  struct sockaddr_in servaddr, cliaddr;  clilen=sizeof(cliaddr);

 for(;;)  {

  /* waiting for receive data */   printf("ready recv data...server_sock:%d\n",server_sock);   nRecvsize = recvfrom(server_sock, mesg, NET_PACKET_SIZE, 0,(struct sockaddr *) &cliaddr, &clilen); //problems         //sendto(server_sock, mesg, nRecvsize, 0, (struct sockaddr *)&cliaddr, clilen); //   printf("recvfrom data start....\n\n\n"); //   printf("nPacketSize:%d \n",nRecvsize); //   unsigned char *p=(unsigned char *)mesg; //   for(int i=0;i<nRecvsize;i++) //   { //    printf("%x ",*p++); //    if(i%16==0) //    { //     printf("\n"); //    } //   } //   printf("\n"); //   sendto(server_sock, mesg, nRecvsize, 0, (struct sockaddr *)&cliaddr, clilen); //   continue;  //exit(0);   /* sent data back to client */   //get ip   //char temip[20];   //printf("1\n");   //printf("2\n");   char *tempip=NULL;   //sockaddr_in* ps=(sockaddr_in*)&cliaddr;   printf("s_addr:%d\n",cliaddr.sin_addr.s_addr);   tempip = inet_ntoa(cliaddr.sin_addr);   //char tempip[32]={0};    if ( NULL== (char*) (inet_ntop(AF_INET,&ps->sin_addr.s_addr,tempip,31)) )    {     printf("inet_ntop error\n" );    }   //sprintf(buf_log,"received a connection from %s\n", str);

  //printf("3\n");   int port = ntohs(cliaddr.sin_port);   //printf("4\n");   printf("ip:%s:%d,len:%d,data:%s\n",tempip,port,nRecvsize,mesg);         One_RecvdPacket recvpacket;            memcpy(recvpacket.data,&cliaddr,sizeof(cliaddr));//head cliaddr part   memcpy(recvpacket.data+sizeof(cliaddr), mesg, nRecvsize);

        pthread_mutex_lock(&g_mutex_recevieddata); //Lock(cs); //插入数据到包队列里

       g_ReceviedDataList.push_back(recvpacket);     printf("insert one recv packet to list.....\n");              pthread_mutex_unlock(&g_mutex_recevieddata); //Lock(cs);

  //sendto(sockfd, mesg, n, 0, pcliaddr, len);  }

 pthread_detach(pthread_self());  printf("pthread_detach pthread_self()...\n"); }

 // //         char buff[BUFSIZ]; //         int result; //         fd_set readfd;//,writefd; //         struct timeval tv; //         tv.tv_sec=1; //         tv.tv_usec=0;  //         //           char  m_cbRecvBuf[NET_PACKET_SIZE];  //接收区为大约10包网络数据大小内存 //        char  m_cbDataBuf[NET_PACKET_SIZE];  //缓冲区为大约10包网络数据大小内存  //        int     m_nRecvSize = 0; //        memset( m_cbRecvBuf, 0, sizeof(m_cbRecvBuf) ); //        memset( m_cbDataBuf, 0, sizeof(m_cbDataBuf) ); //               //         for(;;) //         { //                 bzero(buff,sizeof(buff)); //                 FD_ZERO(&readfd); //                 //FD_ZERO(&writefd); //                 //FD_SET(0,&readfd);//检测键盘输入 //                 FD_SET(client_sock,&readfd); //                 if((result=select(client_sock+1,&readfd,NULL,NULL,&tv))==-1)//开始等待输入输出操作 //                 { //                         perror("server select:"); //                         exit(-1); //                 }else if(result==0){ //                         //printf("have no message comming\n"); //                         continue; //                 }else{ //                        printf("message comming...\n"); // //                        if(FD_ISSET(0,&readfd)) // //                        { // //                                /*用户按键事件响应*/ // //                                fgets(buff,sizeof(buff),stdin); // //                                if(!strncasecmp(buff,"quit",4)) // //                                { // //                                        printf("%d client customer exit chat\n",client_sock); // //                                        break; // //                                } // //                                result=send(client_sock,buff,strlen(buff)+1,0); // //                                if(result>0) // //                                { // //                                        printf("send %d byte\n%s\n",result,buff); // //                                        } // //                                else{ // //                                        printf("消息'%s'发送失败!错误代码是%d,错误信息是'%s'\n",buff, errno, strerror(errno)); // //                                        break; // //                                        }                                // //                        } //                         if(FD_ISSET(client_sock,&readfd)) //client data coming //                         { //                                            // 接收数据 //         int nRecvSize = recv(client_sock,m_cbRecvBuf+m_nRecvSize, sizeof(m_cbRecvBuf)-m_nRecvSize, 0); //         if (nRecvSize <= 0) //客服端关闭或者网络出错 //         { //          close(client_sock); //          printf("when recv,server is off connect\n"); //          printf("exit recv data thread......\n"); //          //char ip[20]; //          //get_client_IP(client_sock,ip); //          //printf("exit client IP:%s......\n",ip); //          break;   //break while, exit thread //           //         }else //收到的数据字符串信息,按照十六进制输出 //         { //           char tempRecvbuf[1024]; //           char hexout[1024]; //           memcpy(tempRecvbuf,m_cbRecvBuf+m_nRecvSize,nRecvSize);   //当前这次收到的数据 //           ToHex(tempRecvbuf, nRecvSize, hexout); //           //char ip[20]; //           get_client_IP(client_sock); //           printf("data:\n");  //printf("client IP :%s data:\n",ip); //           //           printf("recv string:%s ,counter %d byte\n",tempRecvbuf,nRecvSize); //           printf("recv 16hex string:%s \n",hexout); //          } //          //         m_nRecvSize += nRecvSize;   // 保存已经接收数据的大小 //      //         while (m_nRecvSize >= sizeof(NetPacketHeader))   // 接收到的数据够不够一个包头的长度 //         {  //            // 读取包头 //            NetPacketHeader* pHead = (NetPacketHeader*) (m_cbRecvBuf); //            const unsigned short nPacketSize = sizeof(NetPacketHeader)+pHead->frame_datalen;    //整个完整一包数据大小,包含包头 //          //            // 判断是否已接收到足够一个完整包的数据 //            if (m_nRecvSize < nPacketSize) //            { //             // 还不够拼凑出一个完整包 //             break; //            } //            //当收到一个完整包数据信息,打印出来它的客服端ip信息 //             //get ip from socket //           socklen_t rsa_len = sizeof(struct sockaddr_in); //              struct sockaddr_in rsa; //              char *ip = NULL; //              int port = 0; //             if(getpeername(client_sock, (struct sockaddr *)&rsa, &rsa_len) == 0) //             { //               ip = inet_ntoa(rsa.sin_addr); //               port = ntohs(rsa.sin_port); //             } //             //printf msg from client //             printf("from client %s: \n",ip); //             //            // 拷贝到数据缓存 //            memcpy(m_cbDataBuf, m_cbRecvBuf, nPacketSize); //          //            // 从接收缓存移除 //            memmove(m_cbRecvBuf, m_cbRecvBuf+nPacketSize, m_nRecvSize); //            m_nRecvSize -= nPacketSize; //          //            // 解密数据,以下省略 //            // ... //          //            // 分派数据包,让应用层进行逻辑处理 //            pHead = (NetPacketHeader*) (m_cbDataBuf); //            //printf pHead //            printf("net_type:%c,doc_ver:%c,frame_datalen:%d\n",pHead->net_type,pHead->doc_ver,pHead->frame_datalen); //            //struct NetPacketHeader  //物理链路1Bytes 协议版本1Bytes 帧长2Bytes //   //            const unsigned short nDataSize = nPacketSize - (unsigned short)sizeof(NetPacketHeader); //            OnServiceData(m_cbDataBuf+sizeof(NetPacketHeader), nDataSize); //             //                        //         } // end-while // //                         }//end if FD_ISSET //                 }//end if-else-select //                         //         }//end for(;;) //        

void *doClientThread(void *pParam) {    int serverSocket=(int)*(int*)pParam;// int i=(int)*(int*)tid;

   doClientRequest(serverSocket);    //close(clientSocket);    //printf("%d >client socket close ok \n",clientSocket);    return NULL; } bool CrcCheckData(const unsigned char* pDataBuffer, unsigned short nDataSize) {   //物理链路  1Bytes 协议版本 1Bytes UDP设备识别号(UDID) 6字节 数据包 校验字节 4字节 帧长 2Bytes 业务数据片段    //校验格式: 物理链路  1Bytes 协议版本  1Bytes UDP设备识别号(UDID) 6字节 帧长  2Bytes 密钥  8字节 业务数据片段  数据包  校验字节  CRC32  4字节

 unsigned char *p=const_cast<unsigned char*>(pDataBuffer);

//  unsigned char data[NET_PACKET_DATA_SIZE]; //  unsigned char *pdata=data; // //  if(nDataSize >NET_PACKET_DATA_SIZE ) //  { //        printf("nDataSize >NET_PACKET_DATA_SIZE\n"); //     exit(0); //  }  p=p+8;  unsigned int rawCrcresult=0;  memcpy(&rawCrcresult,p,4);

 //   p=p-8;//back to start point

 //memcpy(pdata,p,8);  //p=p+12;  //   memcpy(pdata,p,2);//帧长  //p=p+2;//业务数据片段

 //unsigned char crypt[8];//密钥  8字节  //   memset(crypt,0xaa,8);

 //pdata=pdata+10;  //memcpy(pdata,crypt,8);

 //pdata=pdata+8;  //memcpy(pdata,p,nDataSize-14);

 //bool res=false;  //   res=crc32Check( pdata, nDataSize+4, rawCrcresult);

 printf("rawCrcresult 4 bytes uint:%d \n",rawCrcresult);  

 unsigned short int i,k;   //jiajianwei rcu c code part  unsigned int crc = 0xffffffff;  unsigned char* indata = const_cast<unsigned char*>(pDataBuffer);   unsigned char g_GprsKey[8];  /*物理链路 + 协议版本 + UDP 设备号 8 bytet*/  //crc = crc32(crc,indata,8);  crc = GetBufCRC32( indata, crc, 8 );  /*去掉存储CRC校验码的4个字节*/  //crc = crc32(crc,indata+12,len - 12);  // 帧长  crc = GetBufCRC32( indata + 12, crc, 2 );  //密钥  for(i = 0 ;i < 8 ;i ++)  {   g_GprsKey[i] = 0xaa;  }  crc = GetBufCRC32( g_GprsKey, crc, 8 );  // 剩下的数据  crc = GetBufCRC32( indata + 14, crc, nDataSize - 14 );

 printf("crcCheck     4 bytes uint:%d \n",crc);

 bool res=false;         if (rawCrcresult == crc )     {    res=true;     }

 return res;

  //  u32 rawCRCresult=100; //  u8 inbuf[50]; //  u32 len=50; // crc32Check( p, len, rawCRCresult);

} Timestamp get_timestamp(unsigned char *pdata,int len ) {    //9 byte

 //12bit time zone //6 bit ms , 20ms unit  // 2byte year 1byte m/d/h/m/s

 unsigned short timezone;  unsigned short ms;

 

 unsigned char *p=pdata;  unsigned short head=0;  memcpy(&head,p,2);

 timezone=head;  ms=head;

 timezone=timezone>>6; //timzone  ms=ms&0x003a; //111111

 unsigned short year;  unsigned char mon;  unsigned char d;  unsigned char h;  unsigned char m;  unsigned char s;

 unsigned short umon;  unsigned short ud;  unsigned short uh;  unsigned short um;  unsigned short us;

 p=p+2;  memcpy(&year,p,2);  p=p+1;  memcpy(&mon,p,1);  p=p+1;  memcpy(&d,p,1);  p=p+1;  memcpy(&h,p,1);  p=p+1;  memcpy(&m,p,1);  p=p+1;  memcpy(&s,p,1);

 umon=mon;  ud=d;  uh=h;  um=m;  us=s;

 Timestamp tstamp;  tstamp.timezone=timezone;  tstamp.ms=ms*20;  tstamp.year=year;  tstamp.month=umon;  tstamp.day=ud;  tstamp.hour=uh;  tstamp.minute=um;  tstamp.sencond=us;

 return tstamp;

 

} void * SendtoRCUThread(void *pParam) {

 while(1)  {    usleep(1000); // 1ms while run frequency

   bool bget=false;

   One_SendPacket sendpacket;

   pthread_mutex_lock(&g_mutex_senddata); //Lock(cs);  //get one record data from list buffer queue

    for (list<One_SendPacket>::iterator it = g_readySendDataList.begin(); it != g_readySendDataList.end(); ++it)     {      sendpacket=*it;      //memcpy(plogin_info,&recvpacket,sizeof(One_RecvdPacket));      bget=true;      break;//只取前面第一条     }     if(true == bget )     {      g_readySendDataList.pop_front(); //从链表头取出一条后,杀掉这条     }

   pthread_mutex_unlock(&g_mutex_senddata);

   if (false == bget) // if g_readySendDataList size is null , so can't get data    {     //printf("can't get one record data from g_ReceviedDataList.......\n");     continue;

   }else // handle data part    {

    //char SendData[100];//     int nSendsize=0;

    char *p=sendpacket.data;     sockaddr_in  cliaddr;     memcpy(&cliaddr,p,sizeof(sockaddr_in));     p=p+sizeof(sockaddr_in);     bool rescrc;     memcpy(&rescrc,p,sizeof(bool));     

    p=p+1;     NetPacketHeader *pHead=(NetPacketHeader*)p;     //memcpy(&Head,p,sizeof(NetPacketHeader));  //defaul respose udp packet ,because longin packet only first connect          pHead->frame_datalen=3;  //service udp data response

    p=p+sizeof(NetPacketHeader);     //char Frameindex;                 //memcpy(&Frameindex,p,1);     p=p+1;//char Frameindex;  no change     char framecontrl1;     framecontrl1=0x20;//0010 0000     memcpy(p,&framecontrl1,1);     p=p+1;//framecon1     char *framecontrl2=p;

    //memcpy(&framecontrl2,p,1);     p=p+1;framecon2

    p=p+9;//跳过时间戳     char *psevice_total=p;     char service_total=0;     unsigned short service_ID=0;     memcpy(&service_total,p,1); //业务总数1Bytes     p=p+1;     char *psevice_ID=p;     memcpy(&service_ID,p,2);     //p=p+2;

    //char *ser_len=p;  //业务数据长度2Bytes     //p=p+2;     char *pserviceIDdata=p;//业务ID数据内容

    bool isLoginPacket=false;

    printf("SendtoRCUThread..service_total:%d,service_ID:%d\n",service_total,service_ID);

    if ( (service_total == 1) && (service_ID == 0x0012) )//是登录包     {        // D7:1-业务帧,0-响应帧        // D6:1-接收成功 ,0-接收失败        // D5:NC        // D4:1-时间戳 ,0-无时间戳        // D3:1-GPS时间(格林尼治时间) ,0-本地时间        // D2:1-校验,0-无校验        //    D1-D0 预留        //    响应帧的回传的帧ID和收到的业务帧ID一致。

     isLoginPacket=true;      printf("is login packet......\n");

     *framecontrl2=0x40;  //0100 0000   //D7:0-响应帧 D6:1-接收成功  D4:1 0-无时间戳D2:0-无校验

     if (rescrc == true)      {       *framecontrl2= *framecontrl2 & 0xff;   //1111 1111  D7  //abc  def  10 11 12     13 14 15      }else //fail      {

                        *framecontrl2= *framecontrl2 & 0xbf;   //1011 1111      } //      *framecontrl2=*framecontrl2 & 0xd0;//1110 0000  D5 //      *framecontrl2=*framecontrl2 & 0xf0;     //1111 0000  D4 //是登录包-时间戳 //      *framecontrl2=*framecontrl2 & 0xf0;     //1111 0000     //D3:1-GPS时间(格林尼治时间) ,0-本地时间 //      *framecontrl2=*framecontrl2 & 0xf8;     //1111 1000 //D2:1-校验,0-无校验      //D1-D0 预留

 &nbs

标签: prt温度传感器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台