校车定位服务系统多线程TCP服务器

1 篇文章 0 订阅
1 篇文章 0 订阅

在校车定位服务系统中,车载定位前端将位置、温度等信息以GPRS的方式发送到服务器的时候服务器需要编写一个多线程的TCP服务器接收程序,该程序中还要讲接收到的数据存入数据库具体的做法如下面代码:

#include<Winsock2.h>
#include<iostream>
#include<vector>
#include<fstream>
#include<sstream>
#include<list>
#include<cmath>
#include<string>
#include "D:\Workplace\MySQL\mysql-5.5.25-winx64\include\mysql.h"
using namespace std;

#pragma comment(lib, "libmysql.lib") 

MYSQL mysql;
MYSQL_RES *res;
MYSQL_ROW row;

struct GPS{
    int busID;
    char signalLabel[10];
    char time[14];
    char status;
    double latitude;
    char latitude_sphere;
    double longtitude;
    char longtitude_sphere;
    float speed;
    char date[12];
    float direction;
};
struct Parameter{
     SOCKET sockConn;
     SOCKADDR_IN addrClient;
};

void exiterr(int exitcode)
{
    fprintf(stderr,"%s\n",mysql_error(&mysql));
    exit(exitcode);
}

DWORD WINAPI Fun1Proc(
    LPVOID lpParameter
);

DWORD WINAPI Fun2Proc(
    LPVOID lpParameter
);
list<string> split(string str,string separator);

bool match(char *src,int slen,char *flag,int flen)
{
    int k,j;
    for(int i=0;i<slen;i++)
    {
        k=j=0;
        while(src[i+k]==flag[j]&&j<flen)
        {
            k++;
            j++;
        }
        if(j>=flen)
            return true;
    }
    return false;
}

int GetID(int I, int J)
{
     return I + 660 * J;
}
void LoadText(double *TableX,double *TableY,bool& InitTable)
 {
StreamReader("Mars2Wgs.txt"))
      ifstream converseStream("Mars2Wgs.txt",ios::in);
      long data;
      vector<long> dataSet;
      while(converseStream.eof())
      {
          converseStream>>data;
          dataSet.push_back(data);
      }
       int i = 0,len=dataSet.size();
       vector<long>::iterator iter=dataSet.begin();
       while (iter!=dataSet.end())
        {
              //MessageBox.Show(MP.Value);
               if (i % 2 == 0)
               {
                    TableX[i / 2] = (double)(*iter++) / 100000.0;
                }
                else
                {
                    TableY[(i - 1) / 2] = (double)(*iter++) / 100000.0;
                }
                i++;
         }
        InitTable = true;
 }

/// <summary>
/// x是117左右,y是31左右
/// </summary>
/// <param name="xIN"></param>
/// <param name="yIN"></param>
/// <param name="xOUT"></param>
/// <param name="yOUT"></param>
void MarsToWgs(double *TableX,double *TableY,bool InitTable,double xIN, double yIN, double& xOUT, double& yOUT)
{
            int i, j, k;
            double x1, y1, x2, y2, x3, y3, x4, y4, xtry, ytry, dx, dy;
            double t, u;

            if (!InitTable)
                return;

            xtry = xIN;
            ytry = yIN;

            for (k = 0; k < 10; ++k)
            {
                // 只对中国国境内数据转换
                if (xtry < 72 || xtry > 137.9 || ytry < 10 || ytry > 54.9)
                {
                    return;
                }

                i = (int)((xtry - 72.0) * 10.0);
                j = (int)((ytry - 10.0) * 10.0);

                x1 = TableX[GetID(i, j)];
                y1 = TableY[GetID(i, j)];
                x2 = TableX[GetID(i + 1, j)];
                y2 = TableY[GetID(i + 1, j)];
                x3 = TableX[GetID(i + 1, j + 1)];
                y3 = TableY[GetID(i + 1, j + 1)];
                x4 = TableX[GetID(i, j + 1)];
                y4 = TableY[GetID(i, j + 1)];

                t = (xtry - 72.0 - 0.1 * i) * 10.0;
                u = (ytry - 10.0 - 0.1 * j) * 10.0;

                dx = (1.0 - t) * (1.0 - u) * x1 + t * (1.0 - u) * x2 + t * u * x3 + (1.0 - t) * u * x4 - xtry;
                dy = (1.0 - t) * (1.0 - u) * y1 + t * (1.0 - u) * y2 + t * u * y3 + (1.0 - t) * u * y4 - ytry;

                //MarsToWgs是- dx  - dy
                xtry = (xtry + xIN - dx) / 2.0;
                ytry = (ytry + yIN - dy) / 2.0;
            }

            xOUT = xtry;
            yOUT = ytry;

}

/// <summary>
/// x是117左右,y是31左右
/// </summary>
/// <param name="xIN"></param>
/// <param name="yIN"></param>
/// <param name="xOUT"></param>
/// <param name="yOUT"></param>
void WgsToMars(double *TableX,double *TableY,bool InitTable,double xIN, double yIN,double& xOUT,double& yOUT)
{
            int i, j, k;
            double x1, y1, x2, y2, x3, y3, x4, y4, xtry, ytry, dx, dy;
            double t, u;

            if (!InitTable)
                return;

            xtry = xIN;
            ytry = yIN;

            for (k = 0; k < 10; ++k)
            {
                // 只对中国国境内数据转换
                if (xtry < 72 || xtry > 137.9 || ytry < 10 || ytry > 54.9)
                {
                    return;
                }

                i = (int)((xtry - 72.0) * 10.0);
                j = (int)((ytry - 10.0) * 10.0);

                x1 = TableX[GetID(i, j)];
                y1 = TableY[GetID(i, j)];
                x2 = TableX[GetID(i + 1, j)];
                y2 = TableY[GetID(i + 1, j)];
                x3 = TableX[GetID(i + 1, j + 1)];
                y3 = TableY[GetID(i + 1, j + 1)];
                x4 = TableX[GetID(i, j + 1)];
                y4 = TableY[GetID(i, j + 1)];

                t = (xtry - 72.0 - 0.1 * i) * 10.0;
                u = (ytry - 10.0 - 0.1 * j) * 10.0;

                dx = (1.0 - t) * (1.0 - u) * x1 + t * (1.0 - u) * x2 + t * u * x3 + (1.0 - t) * u * x4 - xtry;
                dy = (1.0 - t) * (1.0 - u) * y1 + t * (1.0 - u) * y2 + t * u * y3 + (1.0 - t) * u * y4 - ytry;

                //WgsToMars是+ dx  + dy
                xtry = (xtry + xIN + dx) / 2.0;
                ytry = (ytry + yIN + dy) / 2.0;
            }

            xOUT = xtry;
            yOUT = ytry;
}

void main()
{
    /****加载socket环境*****/
    WORD wVersionRequested;  //socket自带16位数据类型 表示主版本号副版本号
    WSADATA wsaData;   //WSADATA类型是一个结构,描述了Socket库的一些相关信息
    int err;

    wVersionRequested = MAKEWORD( 2, 2 ); //socket专用给WORD赋值 版本号为2,2

    err = WSAStartup( wVersionRequested, &wsaData );//初始化Socket环境  返回0表示初始化成功
    if ( err != 0 ) {               
        return;   //不为0则失败
    } 

    if ( LOBYTE( wsaData.wVersion ) != 2 ||
        HIBYTE( wsaData.wVersion ) != 2 ) {
        WSACleanup( );
        return; 
    }            //若当前的socket库版本不为0则退出socket

    /***********************************/
    //       //
    //       //
    //       //
    /*****socket配置监听地址和端口号******************/

    SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0);//创建socket 默认为internet 协议类型TCP 默认0
    SOCKADDR_IN addrSrv;  //socket发送和接收数据包的地址
    addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);//本地默认IP地址(多网卡IP地址时应当考虑)
    addrSrv.sin_family=AF_INET;//默认internet
    addrSrv.sin_port=htons(60000);//端口号为60000

    /**********绑定socket****************************/
    bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));//绑定socket 其中的SOCKET是一个抽象结构,这里将其具体化

   /***********监听端口********************************/
    listen(sockSrv,5);

    /**************************************************/
    int k=0;
    SOCKADDR_IN addrClient;//socket  ip+port
    int len=sizeof(SOCKADDR);
    SOCKET sockConn[100];//socket数组用于储存接受等待的连接请求后返回的 远端客户端的ip+port
    HANDLE hThread[100];//由对象句柄指定 线程

    //hThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);
    while(1)
    {
        sockConn[k]=accept(sockSrv,(SOCKADDR*)&addrClient,&len);//接受等待的连接请求 返回客户端ip+port
        Parameter parameter;    //Parameter是自定义结构体 
        parameter.sockConn=sockConn[k];//客户端 ip+port
        parameter.addrClient=addrClient;//ip+port
        printf("%d\n",k);//输出当前进程编号
        hThread[k++]=CreateThread(NULL,0,Fun1Proc,(LPVOID)&parameter,0,NULL);//创建线程返回为线程 hThread[k]然后k++
    }                                                                       //入口函数为Fun1Proc 传入参数为parameter
    //closesocket(sockConn);

    for(int i=0;i<k;i++)
    {
        closesocket(sockConn[i]);//关闭socket
        CloseHandle(hThread[i]);//关闭线程释放资源
    }
    //CloseHandle(hThread2);
   WSACleanup();//清楚socket资源


}

DWORD WINAPI Fun1Proc(
    LPVOID lpParameter//LPVOID:默认参数类型
)
{
    /*Parameter *param;
    param=(Parameter*)lpParameter;*/
    SOCKET sockConn=((Parameter*)lpParameter)->sockConn;//将客户端socket还原 ip+port
    SOCKADDR_IN addrClient=((Parameter*)lpParameter)->addrClient;//还原addrClient

    list<string> gpsinfoList;//list<string>变量
    list<string>::iterator iter;//iterator为内存中连续存储的容器 list<string>::iterator 的变量为iter

    GPS recieveGPS; 
    int tmpTime,latitude,longtitude;
    double tmplat,tmplongt;
    char tmpDate[12];
    int k=0,i,slen;
    bool success;
    char tempstr[50];
    char Temper[10];

      while(true)
      {
        char recvBuf[300];
        int ret=recv(sockConn,recvBuf,300,0);//sockt  recv()函数从TCP连接的另一端接收数据
        if(ret==-1)//接收出错则退出
            break;
        printf("%s\n",recvBuf);//打印出接收到的数据
        slen=strlen(recvBuf);//接收到数据的长度

        if(!match(recvBuf,slen,"$GNRMC",6)&&!match(recvBuf,slen,"$GPRMC",6)&&!match(recvBuf,slen,"$BSRMC",6))//模式匹配
            continue;

        if('q'==recvBuf[0])
            break;//如果接收到的第一位为‘q’则退出
        if('V'== recvBuf[25])
            continue;//如果接收到的标志位为V则此次数据不采集

        gpsinfoList=split(recvBuf,",");//将接收到的数据用','分割开来存放在泛类中
        iter=gpsinfoList.begin();//iter指向list<string>的头

        //将容器里面的数据存入GPS变量
        recieveGPS.busID=atoi(((string)*iter).c_str());//atoi()将字符串转换为整形,c_str()返回字符串指针 表示将得到的泛类变量第一个元素付给GPS_BUSID
        cout<<recieveGPS.busID<<"--";

        iter++;
        strcpy(Temper,((string)*iter).c_str());
        cout<<Temper<<"--";

        iter++;
        strcpy(recieveGPS.signalLabel,((string)*iter).c_str());
        strcpy(tempstr,"'");
        strcat(tempstr,recieveGPS.signalLabel);
        strcat(tempstr,"'");
        strcpy(recieveGPS.signalLabel,tempstr);
        cout<<recieveGPS.signalLabel<<"--";
        iter++;
        strcpy((char *)recieveGPS.time,((string)*iter).c_str());
        tmpTime=0;
        for(int d=0;d<2;d++)
            tmpTime=tmpTime*10+recieveGPS.time[d]-'0';
        tmpTime=tmpTime+8;
        recieveGPS.time[0]=tmpTime/10+'0';
        recieveGPS.time[1]=tmpTime%10+'0';//关于时间的一个转变 东八区
        strcpy(tempstr,"'");
        strcat(tempstr,recieveGPS.time);
        strcat(tempstr,"'");
        strcpy(recieveGPS.time,tempstr);
        cout<<recieveGPS.time<<"--";
        iter++;
        recieveGPS.status=((string)*iter).c_str()[0];
        char tempstatus[4];
        tempstatus[0]='\'';
        tempstatus[1]=recieveGPS.status;
        tempstatus[2]='\'';
        tempstatus[3]='\0';
        cout<<tempstatus<<"--";
        iter++;
        recieveGPS.latitude=atof(((string)*iter).c_str());
        latitude=floor(recieveGPS.latitude);
        latitude=latitude-latitude%100;
        tmplat=recieveGPS.latitude-latitude;
        tmplat=tmplat/60;
        recieveGPS.latitude=tmplat*100+latitude;
        cout<<recieveGPS.latitude<<"--";
        iter++;
        recieveGPS.latitude_sphere=((string)*iter).c_str()[0];
        char tempLatitude[4];
        tempLatitude[0]='\'';
        tempLatitude[1]=recieveGPS.latitude_sphere;
        tempLatitude[2]='\'';
        tempLatitude[3]='\0';
        cout<<recieveGPS.latitude_sphere<<"--";
        iter++;
        //istringstream iss1(((string)*iter)); 
        //iss1>>recieveGPS.longtitude;
         recieveGPS.longtitude=atof(((string)*iter).c_str());
        longtitude=floor(recieveGPS.longtitude);
        longtitude=longtitude-longtitude%100;
        tmplongt=recieveGPS.longtitude-longtitude;
        tmplongt=tmplongt/60;
        recieveGPS.longtitude=longtitude+tmplongt*100;
        cout<<recieveGPS.longtitude<<"--";
        iter++;
        recieveGPS.longtitude_sphere=((string)*iter).c_str()[0];
        char tempLongtitude[4];
        tempLongtitude[0]='\'';
        tempLongtitude[1]=recieveGPS.longtitude_sphere;
        tempLongtitude[2]='\'';
        tempLongtitude[3]='\0';
        iter++;
        recieveGPS.speed=atof(((string)*iter).c_str());//速度 节
        iter++;
        iter++;
        strcpy(tmpDate,((string)*iter).c_str());//UTC日期
        recieveGPS.date[0]=tmpDate[4];
        recieveGPS.date[1]=tmpDate[5];
        recieveGPS.date[2]=tmpDate[2];
        recieveGPS.date[3]=tmpDate[3];
        recieveGPS.date[4]=tmpDate[0];
        recieveGPS.date[5]=tmpDate[1];
        recieveGPS.date[6]='\0';
        strcpy(tempstr,"'");
        strcat(tempstr,recieveGPS.date);
        strcat(tempstr,"'");
        strcpy(recieveGPS.date,tempstr);
        cout<<recieveGPS.date<<endl;
        iter++;
        iter++;
        success=true;
        mysql_init(&mysql);//初始数据库MYSQL
        if(!(mysql_real_connect(&mysql,"127.0.0.1","root","w1989321h","gps_gprs",3309,NULL,0)))
            exiterr(1);//链接数据库
    //  if(mysql_real_query(&mysql,"select * from user",strlen("select * from user")))
        //  exiterr(3);
        char str[300];
        sprintf(str,"insert into gpsinformation (signalLabel,busID,time,status,latitude,latitude_sphere,longtitude,longtitude_sphere,speed,date) values(%s,%d,%s,%s,%.6f,%s,%.6f,%s,%.6f,%s)",
            recieveGPS.signalLabel,recieveGPS.busID,recieveGPS.time,tempstatus,recieveGPS.latitude,
            tempLatitude,recieveGPS.longtitude,tempLongtitude,recieveGPS.speed,recieveGPS.date);

         printf("%s\n",str);
        if(mysql_query(&mysql,str))
            success=false;
        printf("%d\n",success);
        mysql_close(&mysql);
        }

   return 0;
}


DWORD WINAPI Fun2Proc(
    LPVOID lpParameter
)
{
  return 0;
}

/**********按一定格式分割字符串*************************/
/****************返回的块存入泛类******************************/

list<string> split(string str,string separator)//字符串地址,分割符
{
    list<string> result;
    int cutAt;
    while((cutAt=str.find_first_of(separator))!=str.npos)
    {
        if(cutAt>0)
        {
            result.push_back(str.substr(0,cutAt));
        }
        str=str.substr(cutAt+1);
    }
    if(str.length()>0)
    {
        result.push_back(str);
    }
    return result;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值