校车定位服务系统多线程TCP服务器
在校车定位服务系统中,车载定位前端将位置、温度等信息以GPRS的方式发送到服务器的时候服务器需要编写一个多线程的TCP服务器接收程序,该程序中还要讲接收到的数据存入数据库具体的做法如下面代码:
#include
#include
#include
#include
#include
#include
#include
#include
#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;i0;while(src[i+k]==flag[j]&&jif(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;}///
/// x是117左右,y是31左右
///
///
///
///
///
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 - dyxtry = (xtry + xIN - dx) / 2.0;ytry = (ytry + yIN - dy) / 2.0;}xOUT = xtry;yOUT = ytry;}///
/// x是117左右,y是31左右
///
///
///
///
///
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 + dyxtry = (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,2err = 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 默认0SOCKADDR_IN addrSrv; //socket发送和接收数据包的地址addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);//本地默认IP地址(多网卡IP地址时应当考虑)addrSrv.sin_family=AF_INET;//默认internetaddrSrv.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+portint len=sizeof(SOCKADDR);SOCKET sockConn[100];//socket数组用于储存接受等待的连接请求后返回的 远端客户端的ip+portHANDLE hThread[100];//由对象句柄指定 线程//hThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);while(1){sockConn[k]=accept(sockSrv,(SOCKADDR*)&addrClient,&len);//接受等待的连接请求 返回客户端ip+portParameter parameter; //Parameter是自定义结构体 parameter.sockConn=sockConn[k];//客户端 ip+portparameter.addrClient=addrClient;//ip+portprintf("%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//关闭socketCloseHandle(hThread[i]);//关闭线程释放资源}//CloseHandle(hThread2);WSACleanup();//清楚socket资源}DWORD WINAPI Fun1Proc(LPVOID lpParameter//LPVOID:默认参数类型
)
{/*Parameter *param;param=(Parameter*)lpParameter;*/SOCKET sockConn=((Parameter*)lpParameter)->sockConn;//将客户端socket还原 ip+portSOCKADDR_IN addrClient=((Parameter*)lpParameter)->addrClient;//还原addrClientlist<string> gpsinfoList;//list变量 list<string>::iterator iter;//iterator为内存中连续存储的容器 list::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的头 //将容器里面的数据存入GPS变量recieveGPS.busID=atoi(((string)*iter).c_str());//atoi()将字符串转换为整形,c_str()返回字符串指针 表示将得到的泛类变量第一个元素付给GPS_BUSIDcout<"--";iter++;strcpy(Temper,((string)*iter).c_str());cout<"--";iter++;strcpy(recieveGPS.signalLabel,((string)*iter).c_str());strcpy(tempstr,"'");strcat(tempstr,recieveGPS.signalLabel);strcat(tempstr,"'");strcpy(recieveGPS.signalLabel,tempstr);cout<"--";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<"--";iter++;recieveGPS.status=((string)*iter).c_str()[0];char tempstatus[4];tempstatus[0]='\'';tempstatus[1]=recieveGPS.status;tempstatus[2]='\'';tempstatus[3]='\0';cout<"--";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<"--";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<"--";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<"--";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<true;mysql_init(&mysql);//初始数据库MYSQLif(!(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;
}
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
