18,356
社区成员
发帖
与我相关
我的任务
分享
void CatchUpsData()
{
if (_beginthread(CatchUpsData22, 0,NULL) == NULL)
{
printf("主动取数据线程开启失败!\n");
}
else
{
printf("主动取数据线程开启成功!\n");
}
}
SOCKET m_CatchSocket;
sockaddr_in m_OctopusAddr;
void CatchUpsData22(void * t)
{
Sleep(10 * 1000);
WSADATA wsaData;
if (WSAStartup(0x0202, &wsaData) != 0)//WSAStartup 调用Socket前必须指定版本
{
printf("WSAStartup failed with error\n" );
return ;
}
// Create a listening socket
if ((m_CatchSocket = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, //流的方式创建Sock
WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET)
{
printf("WSASocket() failed with error %d\n", WSAGetLastError());
return ;
}
char host_name[255];
//获取本地主机名称
if (gethostname(host_name, sizeof(host_name)) == SOCKET_ERROR)
{
printf("Error %d when getting local host name.n", WSAGetLastError());
return ;
}
struct hostent *phe = gethostbyname(host_name);
struct in_addr addr;
memcpy(&addr, phe->h_addr_list[0], sizeof(struct in_addr));
m_OctopusAddr.sin_family = AF_INET;
m_OctopusAddr.sin_addr.s_addr = inet_addr(inet_ntoa(addr));
m_OctopusAddr.sin_port = htons(6018);
if(connect(m_CatchSocket,(sockaddr *)&m_OctopusAddr,sizeof(m_OctopusAddr)) == -1)
{
printf("本地连接Socket失败!%d\n",WSAGetLastError());
return ;
}
else
{
CatchUpsMake(true); //开始死循环,取数据
}
//关闭连接
if (closesocket(m_CatchSocket) == SOCKET_ERROR)
{
printf("closesocket() failed with error %d\n", WSAGetLastError());
}
}
// 取出SOCKET连接客户端的ip地址
CHAR * GetIP(SOCKET s)
{
struct sockaddr_in name;
int namelen = sizeof(struct sockaddr_in);
if(0 != getpeername(s, (sockaddr *)&name, &namelen))
{
printf("Get client address from SOCKET failed\n");
return NULL;
}
else
{
// 得到地址字符串
return inet_ntoa(name.sin_addr);
}
}
void CatchUpsMake(bool bFlag)
{
char DataBuff[1024]; //缓存
memset(DataBuff,'\0',1024);
printf("开始循环读取数据!\n");
while(bFlag)
{
//计时
SYSTEMTIME OldTime;
GetLocalTime(&OldTime);
TCHAR * config_dir = getAppConfigDir();//每30秒循环时,读一次config.ini文件
int iTimeOutConn = GetPrivateProfileInt(L"Time Out",L"TimeOutConn",100,config_dir);
int iTimeOutSend = GetPrivateProfileInt(L"Time Out",L"TimeOutSend",100,config_dir);
int iTimeOutRecv = GetPrivateProfileInt(L"Time Out",L"TimeOutRecv",100,config_dir);
if(0 == iTimeOutConn)
{
printf("读取连接超时失败,将使用默认超时!\n");
iTimeOutConn = 300;
}
if(0 == iTimeOutSend)
{
printf("读取发送超时失败,将使用默认超时!\n");
iTimeOutSend = 100;
}
if(0 == iTimeOutRecv)
{
printf("读取接收超时失败,将使用默认超时!\n");
iTimeOutRecv = 100;
}
printf("\n");
for (DWORD index=0; index<g_connections.size(); index++)
{
SOCKET OneSocket;
sockaddr_in UpsAddr;
WSADATA wsaData;
DWORD Ret;
if ((Ret = WSAStartup(0x0202, &wsaData)) != 0)//WSAStartup 调用Socket前必须指定版本
{
printf("WSAStartup failed with error %d\n", Ret);
continue;
}
// Create a listening socket
if ((OneSocket = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, //流的方式创建Sock
WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET)
{
printf("WSASocket() failed with error %d\n", WSAGetLastError());
continue;
}
UpsAddr.sin_family = AF_INET;//固定的
UpsAddr.sin_addr.s_addr = inet_addr(g_connections[index].IP);
UpsAddr.sin_port = htons(100);//htons 网络字节序
unsigned long desIP = UpsAddr.sin_addr.S_un.S_addr;//四字节ip形式
BYTE * pIp = (BYTE *)&desIP;
BYTE ip1 = *pIp;
BYTE ip2 = *(pIp+1);
BYTE ip3 = *(pIp+2);
BYTE ip4 = *(pIp+3);
//设置超时
BOOL bOptVal = TRUE;
int bOptLen = sizeof(BOOL),iOptVal =2,iOptLen = sizeof(int);
if (setsockopt(OneSocket, SOL_SOCKET, SO_SNDTIMEO, (char*)&bOptVal, bOptLen) == SOCKET_ERROR)
{
printf("设置超时失败!\n");
continue;
}
if (setsockopt(OneSocket, SOL_SOCKET, SO_RCVTIMEO, (char*)&bOptVal, bOptLen) == SOCKET_ERROR)
{
printf("设置超时失败!\n");
continue;
}
//设置非阻塞方式连接
unsigned long ul = 1;
int ret = ioctlsocket(OneSocket, FIONBIO, (unsigned long*)&ul);
if(ret==SOCKET_ERROR)
continue;
connect(OneSocket,(sockaddr *)&UpsAddr,sizeof(UpsAddr)); //连接
//select 模型,即设置超时
struct timeval timeout ;
fd_set r;
FD_ZERO(&r);
FD_SET(OneSocket, &r);
timeout.tv_sec = 0;
timeout.tv_usec =iTimeOutConn;//连接超时,微妙
ret = select(0, 0, &r, 0, &timeout);
if ( ret <= 0 )
{
closesocket(OneSocket);
printf("%s连接失败!%d\n",g_connections[index].IP,WSAGetLastError());
continue;
}
//一般非锁定模式套接比较难控制,可以根据实际情况考虑 再设回阻塞模式
unsigned long ul1= 0 ;
ret = ioctlsocket(OneSocket, FIONBIO, (unsigned long*)&ul1);
if(ret==SOCKET_ERROR)
{
closesocket (OneSocket);
continue;
}
const char * Cmd = "UPSLOG";
int iSucessS = send(OneSocket,Cmd, 6, 0);//发指令
int iSucessR = recv(OneSocket, DataBuff, 1024, 0);//读数据
if(iSucessR == -1 && iSucessR == 0)//没有接收到数据
{
if (closesocket(OneSocket) == SOCKET_ERROR)//关闭连接
{
printf("closesocket() failed with error %d\n", WSAGetLastError());
continue;
}
WSACleanup();
continue;
}
//帧尾加UPS的ip
CHAR * UpsIp =GetIP(OneSocket);
CHAR * temp = "-";
strcat(DataBuff,temp);
strcat(DataBuff,UpsIp);
CHAR * temp2= "EE";
strcat(DataBuff,temp2);
if (closesocket(OneSocket) == SOCKET_ERROR)//关闭连接
{
printf("closesocket() failed with error %d\n", WSAGetLastError());
continue;
}
WSACleanup();
/* 转发 */
int iSucessOctopus = send(m_CatchSocket,DataBuff, 1024, 0);
/* 没发送成功,重连 */
if(iSucessOctopus == -1)
{
WSACleanup();
if (WSAStartup(0x0202, &wsaData) != 0)
{
printf("WSAStartup failed with error\n" );
return ;
}
// Create a listening socket
if ((m_CatchSocket = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0,
WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET)
{
printf("WSASocket() failed with error %d\n", WSAGetLastError());
return ;
}
if(connect(m_CatchSocket,(sockaddr *)&m_OctopusAddr,sizeof(m_OctopusAddr)) == -1)
{
printf("重新连接Socket失败!%d\n",WSAGetLastError());
continue ;
}
else
{ /* 重新发送 发送是否成功不做判断 */
iSucessOctopus = send(m_CatchSocket,DataBuff, 1024, 0);
}
}
g_connections[index].times ++;//做计数
memset(DataBuff,'\0',1024);
}
//计时是否到三十秒//系统时间//计时
SYSTEMTIME NewTime;
GetLocalTime(&NewTime);
WORD iC = (NewTime.wMinute-OldTime.wMinute) *60 + (NewTime.wSecond-OldTime.wSecond);
if( iC<30)
{
Sleep((30- iC) * 1000);//延迟
}
else
{
continue;
}
}
}
void CatchUpsMake(bool bFlag)
{
char DataBuff[1024]; //缓存
memset(DataBuff,'\0',1024);
printf("开始循环读取数据!\n");
while(bFlag)
{
//计时
SYSTEMTIME OldTime;
GetLocalTime(&OldTime);
TCHAR * config_dir = getAppConfigDir();//每30秒循环时,读一次config.ini文件
int iTimeOutConn = GetPrivateProfileInt(L"Time Out",L"TimeOutConn",2000,config_dir);
int iTimeOutSend = GetPrivateProfileInt(L"Time Out",L"TimeOutSend",2000,config_dir);
int iTimeOutRecv = GetPrivateProfileInt(L"Time Out",L"TimeOutRecv",2000,config_dir);
if(0 == iTimeOutConn)
{
printf("读取连接超时失败,将使用默认超时!\n");
iTimeOutConn = 2000;
}
if(0 == iTimeOutSend)
{
printf("读取发送超时失败,将使用默认超时!\n");
iTimeOutSend = 2000;
}
if(0 == iTimeOutRecv)
{
printf("读取接收超时失败,将使用默认超时!\n");
iTimeOutRecv = 2000;
}
printf("\n");
for (DWORD index=0; index<g_connections.size(); index++)
{
SOCKET OneSocket;
sockaddr_in UpsAddr;
WSADATA wsaData;
DWORD Ret;
if ((OneSocket = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, //流的方式创建Sock
WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET)
{
printf("WSASocket() failed with error %d\n", WSAGetLastError());
continue;
}
UpsAddr.sin_family = AF_INET;//固定的
UpsAddr.sin_addr.s_addr = inet_addr(g_connections[index].IP);
UpsAddr.sin_port = htons(100);//htons 网络字节序
//设置超时
BOOL bOptVal = TRUE;
int bOptLen = sizeof(BOOL),iOptVal =2,iOptLen = sizeof(int);
if (setsockopt(OneSocket, SOL_SOCKET, SO_SNDTIMEO, (char*)&bOptVal, bOptLen) == SOCKET_ERROR)
{
printf("设置超时失败!\n");
continue;
}
if (setsockopt(OneSocket, SOL_SOCKET, SO_RCVTIMEO, (char*)&bOptVal, bOptLen) == SOCKET_ERROR)
{
printf("设置超时失败!\n");
continue;
}
//设置非阻塞方式连接
unsigned long ul = 1;
int ret = ioctlsocket(OneSocket, FIONBIO, (unsigned long*)&ul);
if(ret==SOCKET_ERROR)
continue;
connect(OneSocket,(sockaddr *)&UpsAddr,sizeof(UpsAddr)); //连接
//select 模型,即设置超时
struct timeval timeout ;
fd_set r;
FD_ZERO(&r);
FD_SET(OneSocket, &r);
timeout.tv_sec = 0;
timeout.tv_usec =iTimeOutConn;//连接超时,微妙
ret = select(0, 0, &r, 0, &timeout);
if ( ret <= 0 )
{
closesocket(OneSocket);
printf("%s连接失败!%d\n",g_connections[index].IP,WSAGetLastError());
continue;
}
//一般非锁定模式套接比较难控制,可以根据实际情况考虑 再设回阻塞模式
unsigned long ul1= 0 ;
ret = ioctlsocket(OneSocket, FIONBIO, (unsigned long*)&ul1);
if(ret==SOCKET_ERROR)
{
closesocket (OneSocket);
continue;
}
const char * Cmd = "UPSLOG";
int iSucessS = send(OneSocket,Cmd, 6, 0);//发指令
int iSucessR = recv(OneSocket, DataBuff, 1024, 0);//读数据
if(iSucessR == -1 && iSucessR == 0)//没有接收到数据
{
if (closesocket(OneSocket) == SOCKET_ERROR)//关闭连接
{
printf("closesocket() failed with error %d\n", WSAGetLastError());
continue;
}
continue;
}
//帧尾加UPS的ip
CHAR * UpsIp =GetIP(OneSocket);
CHAR * temp = "-";
strcat(DataBuff,temp);
strcat(DataBuff,UpsIp);
CHAR * temp2= "EE";
strcat(DataBuff,temp2);
if (closesocket(OneSocket) == SOCKET_ERROR)//关闭连接
{
printf("closesocket() failed with error %d\n", WSAGetLastError());
continue;
}
/* 转发 */
int iSucessOctopus = send(m_CatchSocket,DataBuff, 1024, 0);
/* 没发送成功,重连 */
if(iSucessOctopus == -1)
{
if ((m_CatchSocket = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0,
WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET)
{
printf("WSASocket() failed with error %d\n", WSAGetLastError());
return ;
}
if(connect(m_CatchSocket,(sockaddr *)&m_OctopusAddr,sizeof(m_OctopusAddr)) == -1)
{
printf("重新连接Socket失败!%d\n",WSAGetLastError());
continue ;
}
else
{ /* 重新发送 发送是否成功不做判断 */
iSucessOctopus = send(m_CatchSocket,DataBuff, 1024, 0);
}
}
g_connections[index].times ++;//做计数
memset(DataBuff,'\0',1024);
}
//计时是否到三十秒//系统时间//计时
SYSTEMTIME NewTime;
GetLocalTime(&NewTime);
WORD iC = (NewTime.wMinute-OldTime.wMinute) *60 + (NewTime.wSecond-OldTime.wSecond);
if( iC < MAX_INTERVAL_TIME)
{
Sleep((MAX_INTERVAL_TIME- iC) * 1000);//延迟
}
else
{
continue;
}
}
}
/* 在头文件中定义消息响应函数 */
afx_msg void OnSocket(WPARAM wParam, LPARAM lParam);
/* cpp 中 */
#define WM_SOCKET WM_USER+100 //定义WM_SOCKET消息
BEGIN_MESSAGE_MAP()
ON_MESSAGE(WM_SOCKET,OnSocket) //关联消息和相应函数
END_MESSAGE_MAP()
SOCKET m_socket;//侦听的socket
SOCKET ClientSocket;//用来保存连接上的客户端的Socket
sockaddr_in remoteClient;//用来保存连接上的客户端地址
m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
bind(m_socket,(sockaddr*)&serverAddr,sizeof(serverAddr));//绑定端口
listen(m_socket,5);//开始侦听
WSAAsyncSelect(m_socket, m_hWnd,
WM_SOCKET, FD_ACCEPT );//通知窗口,接收WM_SOCKET消息
OnSocket(WPARAM wParam, LPARAM lParam)
{
SOCKET s = wParam;
int pSize = sizeof(remoteClient);
switch(WSAGETSELECTEVENT(lParam))
{
case FD_ACCEPT:
{
ClientSocket = accept(s,(sockaddr*)&remoteClient,&pSize);
break;
}
}
1. 添加通讯线程,使用tcp协议发送命令字,主动从UPS控制器取数据。
2. 得到数据后在帧尾添加UPS控制器IP转发给本机6018端口。(Ip为4字节或字符串形式)
3. 原通讯程序可以不动,尽量减小变动。(帧内容解析时,解析出ip)
Main()
{
…..
//原通讯线程打开之后,延迟十秒开启本通讯线程Thread()
}
Thread
Sleep(10 * 1000) //延迟10秒
m_Socket =new Socket(local,6018)//和本地的连接
try
m_Socket.connect();
bFlag = true;
While(bFlag) //死循环,单独写成函数
Time = dataTime.now.//本次遍历开始的时间,遍历结束时判断是否超过30秒,不到30秒的延迟到30秒。
For(int i=0;i< g_connectons.size;i++)
try
Ip = g_conections[i].ip;
OneSocket = new Socket(Ip,100) //连接控制器
If(OneSocket.connect)
OneSocket.Send(“UPSLOG”); //发指令
OneSocket.Read(Data); //读应答
OneSocket.Close();
Data += ip;
M_Socket.Send(Data) //转发本地6018端口
Else
//连接不成功
Catch
//没有连接成功
End For
//判断时间是否到30秒做延迟
End While
Catch
//和本地的连接失败
sockaddr_in UpsAddr;
WSADATA wsaData;
DWORD Ret;
if ((Ret = WSAStartup(0x0202, &wsaData)) != 0)//WSAStartup 调用Socket前必须指定版本
{
printf("WSAStartup failed with error %d\n", Ret);
continue;
}