在校车定位服务系统中,车载定位前端将位置、温度等信息以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)¶meter,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;
}