//формирование структур времени
tmBegin.tm_sec = Form1->ComboBox3->ItemIndex;
tmBegin.tm_min = Form1->ComboBox2->ItemIndex;
tmBegin.tm_hour = Form1->ComboBox6->ItemIndex;
tmBegin.tm_mday = Form1->ComboBox8->ItemIndex+1;
tmBegin.tm_mon = Form1->ComboBox10->ItemIndex;
tmBegin.tm_year = Form1->ComboBox12->ItemIndex+70;
tmBegin.tm_isdst = 0;
time_tBegin = mktime(&tmBegin);
if (time_tBegin == -1)
{
Application->MessageBoxA("Ошибка преобразования начального времени", "Error!", MB_OK);
Form1->Button3->Enabled = TRUE;
return;
}
tmEnd.tm_sec = Form1->ComboBox5->ItemIndex;
tmEnd.tm_min = Form1->ComboBox4->ItemIndex;
tmEnd.tm_hour = Form1->ComboBox7->ItemIndex;
tmEnd.tm_mday = Form1->ComboBox9->ItemIndex+1;
tmEnd.tm_mon = Form1->ComboBox11->ItemIndex;
tmEnd.tm_year = Form1->ComboBox13->ItemIndex+70;
tmEnd.tm_isdst = 0;
time_tEnd = mktime(&tmEnd);
if (time_tBegin == -1)
{
Application->MessageBoxA("Ошибка преобразования конечного времени", "Error!", MB_OK);
Form1->Button3->Enabled = TRUE;
return;
}
if (time_tEnd < time_tBegin)
{
Application->MessageBoxA("Конечное время меньше начального", "Error!", MB_OK);
Form1->Button3->Enabled = TRUE;
return;
}
Далі програма відправить запит та надасть отримані дані або повідомить про відсутність даних у цьому діапазоні.
reqRange.typeRequest = 2;
reqRange.typeSender = 5;
reqRange.lengthPack = sizeof (requestRange);
reqRange.iTypeUVM = iTypeUVM;
reqRange.tBegin = time_tBegin;
reqRange.tEnd = time_tEnd;
nLeft = reqRange.lengthPack;
idx = 0;
while(nLeft > 0)
{
ret = send(sClient, ((char *)&reqRange) + idx, nLeft, 0);
if (ret == SOCKET_ERROR)
{
Application->MessageBoxA("Ошибка отправки запроса на приём данных", "Error!", MB_OK);
CloseClientSocket();
return;
}
nLeft -= ret;
idx += ret;
}
nLeft = sizeof(packageServer);
idx = 0;
while(nLeft > 0)
{
ret = recv(sClient, ((char *)&packServ)+idx, nLeft, 0);
if ((ret == SOCKET_ERROR)||(ret == 0))
{
Application->MessageBoxA("Ошибка приёма количества данных", "Error!", MB_OK);
CloseClientSocket();
return;
}
nLeft -= ret;
idx += ret;
}
if (packServ.AmountPacks == 0)
{
Application->MessageBoxA("Нет данных в заданном диапазоне времени", "Error!", MB_OK);
Form1->Button3->Enabled = TRUE;
return;
}
StringGrid1->RowCount = packServ.AmountPacks+1;
for (i = 0; i<packServ.AmountPacks; i++)
{
if (iTypeUVM == 1)
nLeft = sizeof(package1);
else
nLeft = sizeof(package2);
idx = 0;
while(nLeft > 0)
{
if (iTypeUVM == 1)
ret = recv(sClient, ((char *)&pack1)+idx, nLeft, 0);
else
ret = recv(sClient, ((char *)&pack2)+idx, nLeft, 0);
if ((ret == SOCKET_ERROR)||(ret == 0))
{
Application->MessageBoxA("Ошибка приёма структуры данных", "Error!", MB_OK);
CloseClientSocket();
return;
}
nLeft -= ret;
idx += ret;
}//while
Додаток А. Вихідний текст КОМ
//---------------------------------------------------------------------------
#include <time.h>
#include <vcl.h>
#pragma hdrstop
#pragma argsused
#include <winsock2.h>
#include "UVM.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
#include <process.h>
typedef unsigned char uc;
typedef unsigned short int ui;
#pragma pack (push)
#pragma pack (1)
typedef struct
{
uc typeRequest;
uc typeSender;
uc lengthPack;
time_t time;
uc speed1;
uc speed2;
ui temperature1;
ui temperature2;
ui temperature3;
ui weight1;
ui weight2;
ui weight3;
uc length1;
uc length2;
} package1;
typedef struct
{
uc typeRequest;
uc typeSender;
uc lengthPack;
time_t time;
uc speed1;
uc speed2;
uc speed3;
ui temperature1;
ui temperature2;
ui weight1;
ui weight2;
ui weight3;
ui weight4;
uc length;
} package2;
typedef struct
{
uc typeRequest; //0 - запрос на синхронизацию
//1 - данные от УВМ
//2 - запрос от клиента
uc typeSender; //1..4 номер УВМ
//5 клиент
uc lengthPack;
} request;
#pragma pack (pop)
TForm1 *Form1;
SOCKET sUvm;
HANDLE hEvent, hThreadUVM;
char bEndThread = 0;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
unsigned __stdcall UVMThread(LPVOID lpParam)
{
WSADATA wsd;
struct sockaddr_in server;
AnsiString sAddress, sPort, sNumUVM;
char * cAddress, * cPort, * cNumUVM;
char cBufTime[4], i;
unsigned int lenAdr, lenPort, iPort, iUVM,
idx, nLeft, ret;
uc bConnect, bTimeSync;
uc period;
request req;
package1 pack1 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
package2 pack2 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
char * pPack;
time_t curTime, lastUpdateTime, lastSendTime = 0;
DWORD timeToSleep;
Form1->Button1->Enabled = FALSE;
//создание события для временного прерывания работы программы
hEvent = CreateEvent( NULL, FALSE, FALSE, NULL);
// преобразование адреса
sAddress = Form1->Edit2->Text;
cAddress = sAddress.c_str();
lenAdr = sAddress.Length();
cAddress[lenAdr] = '\0';
//преобразование порта
sPort = Form1->Edit3->Text;
cPort = sPort.c_str();
lenPort = sPort.Length();
cPort[lenPort] = '\0';
iPort = atoi(cPort);
//преобразование номера УВМ
sNumUVM = Form1->ComboBox1->Text;
cNumUVM = sNumUVM.c_str();
cNumUVM[1] = '\0';
iUVM = atoi(cNumUVM);
//формирование постоянных значений структур
req.typeRequest = 0;
req.typeSender = iUVM;
req.lengthPack = sizeof(request);
if (iUVM == 2)
{
pack1.weight1 = 0xFFFF;
}
if (iUVM == 4)
{
pack2.weight1 = 0xFFFF;
}
if (iUVM <3)
{
period = 14;
pack1.typeRequest = 1;
pack1.typeSender = iUVM;
pack1.lengthPack = sizeof(pack1);
pPack = (char *)&pack1;
}
else
{
period = 5;
pack2.typeRequest = 1;
pack2.typeSender = iUVM;
pack2.lengthPack = sizeof(pack2);
pPack = (char *)&pack2;
}
if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
{
return 0;
}
//создание сокета
sUvm = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sUvm == INVALID_SOCKET)
{
return 0;
}
server.sin_family = AF_INET;
server.sin_port = htons(iPort);
server.sin_addr.s_addr = inet_addr(cAddress);
if (server.sin_addr.s_addr == INADDR_NONE)
{
// Если не указан IP-адрес
return 0;
}
//подсоединение к серверу
if (connect(sUvm, (struct sockaddr *)&server,
sizeof(server)) == SOCKET_ERROR)
bConnect = 1;
else
bConnect = 0;
bTimeSync = 1;
while (!bEndThread)
{
//подключение к серверу
if (bConnect)
{
shutdown(sUvm, SD_BOTH);
closesocket(sUvm);
sUvm = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (!(connect(sUvm, (struct sockaddr *)&server,
sizeof(server)) == SOCKET_ERROR))
{
bConnect = 0;
bTimeSync = 1;
}
}//if
//отправка запроса на синхронизацию времени
if ((!bConnect) && (bTimeSync))
{
nLeft = req.lengthPack;
idx = 0;
while(nLeft > 0)
{
ret = send(sUvm, ((char *)&req) + idx, nLeft, 0);
if (ret == SOCKET_ERROR)
{
bConnect = 1;
break;
}
nLeft -= ret;
idx += ret;
}
}//if
//приём времени сервера и установка его в системе
if ((!bConnect) && (bTimeSync))
{
nLeft = 4;
idx = 0;
while(nLeft > 0)
{
ret = recv(sUvm, ((char *)&lastUpdateTime)+idx, nLeft, 0);
if ((ret == SOCKET_ERROR)||(ret == 0))
{
bConnect = 1;
break;
}
nLeft -= ret;
idx += ret;
}
bTimeSync = 0;
// установка времени в системе
//stime(&lastUpdateTime);
}//if
//остановка работы до контрольной точки отсылки
if (!bConnect)
{
curTime = time(NULL);
if (lastSendTime == curTime)
timeToSleep = period * 1000;
else
timeToSleep = (period-(curTime % period))*1000;
WaitForSingleObject(hEvent, timeToSleep);
}
//считывание датчиков и текущего времени, отправка пакета
if (!bConnect)
{
if (iUVM < 3)
{
//считывание времени и установка параметров
curTime = time(NULL);
pack1.time = curTime;
nLeft = sizeof(pack1);
}
else
{
//считывание времени и установка параметров
curTime = time(NULL);
pack2.time = curTime;
nLeft = sizeof(pack2);
}
lastSendTime = time(NULL);
idx = 0;
while(nLeft > 0)
{
ret = send(sUvm, pPack+idx, nLeft, 0);
if (ret == SOCKET_ERROR)
{
bConnect = 1;
break;
}
nLeft -= ret;
idx += ret;
}
}//if
//проверка необходимости на повторную синхронизацию
if (!bConnect)
{
if ((time (NULL) - lastUpdateTime) > 600)
bTimeSync = 1;
}//if
}//while
WSACleanup();
CloseHandle(hEvent);
// Form1->Button1->Enabled = TRUE;
return 0;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
UINT iThreadId;
int i = 2;
Form1->Button1->Enabled = FALSE;
hThreadUVM = (HANDLE)_beginthreadex(NULL, 0, UVMThread, (LPVOID)i, 0,
&iThreadId);
if (hThreadUVM == NULL)
{
return;
}
return;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
if (sUvm != NULL)
{
bEndThread = 1;
shutdown(sUvm, SD_BOTH);
closesocket(sUvm);
SetEvent (hEvent);
WaitForSingleObject(hThreadUVM, INFINITE);
CloseHandle (hThreadUVM);
}
}
//---------------------------------------------------------------------------
Додаток Б
Вихідний текст серверу
#include <vcl.h>
#pragma hdrstop
#include "Server.h"
#pragma package(smart_init)
#pragma resource "*.dfm"
#include <winsock2.h>
#include <process.h>
#include <time.h>
#include <fcntl.h>
#include <stdio.h>
#include <conio.h>
#define MAX_CLIENT 10
#define timeToSleep 10000
typedef unsigned char uc;
typedef unsigned short int ui;
#pragma pack (push)
#pragma pack (1)
typedef struct
{
time_t time;
uc speed1;
uc speed2;
ui temperature1;
ui temperature2;
ui temperature3;
ui weight1;
ui weight2;
ui weight3;
uc length1;
uc length2;
} package1;
typedef struct
{
time_t time;
uc speed1;
uc speed2;
uc speed3;
ui temperature1;
ui temperature2;
ui weight1;
ui weight2;
ui weight3;
ui weight4;
uc length;
} package2;
typedef struct
{
uc typeRequest; //0 - запрос на синхронизацию
//1 - данные от УВМ
//2 - запрос от клиента
//3 - данные от сервера
uc typeSender; //1..4 номер УВМ
//5 клиент
//6 сервер
uc lengthPack;
} request;
typedef struct
{
ui iTypeUVM;
time_t tBegin;
time_t tEnd;
} requestRange;
typedef struct
{
uc typeRequest;
uc typeSender;
uc lengthPack;
unsigned long AmountPacks;
} packageServer;
typedef struct
{
HANDLE hClientThread;
SOCKET sClient;
time_t time;
uc typeSender;
}SOCKET_INFORMATION;
#pragma pack (pop)
//---------------------------------------------------------------------------
//прототипы функций
void DeleteSockInfo(int, uc);
//---------------------------------------------------------------------------
//глобальные переменные
TForm1 *Form1;
WSADATA wsd;
SOCKET sListen;
HANDLE hThreadAccept, hThreadControl;
HANDLE hEvent;
char bAlowCloseClient[MAX_CLIENT];
BOOL bServWorking = FALSE;
CRITICAL_SECTION csFile;
FILE *f1;
FILE *f2;
time_t lastTimeGroup1 = 0, lastTimeGroup2 = 0;
CRITICAL_SECTION cs;
int iNumClients = 0;
SOCKET_INFORMATION sockInfo[MAX_CLIENT];
//---------------------------------------------------------------------------
unsigned __stdcall ClientThread(LPVOID lpParam)
{
int nClient=(int)lpParam;
unsigned int idx, nLeft, ret, iFound;
request req;
requestRange reqRange;
packageServer packServ;
uc bError = 0, TypeSender;
time_t curTime;
package1 pack1;
package1 * pack1Array;
package2 pack2;
package2 * pack2Array;
long int curPos, endPos, startPos;
unsigned int i, nStructs;
while (!bError)
{
//приём запроса клиента
nLeft = sizeof(request);
idx = 0;
while(nLeft > 0)
{
ret = recv(sockInfo[nClient].sClient, ((char *) &req)+idx, nLeft, 0);
if ((ret == SOCKET_ERROR)||(ret == 0))
{
bError = 1;
break;
}
nLeft -= ret;
idx += ret;
}
//установка типа клиента при получении первого запроса
if ((TypeSender == 0) && (!bError))
{
EnterCriticalSection (&cs);
sockInfo[nClient].typeSender = req.typeSender;
LeaveCriticalSection (&cs);
TypeSender = req.typeSender;
}
//запрос на синхронизацию?
if ((req.typeRequest == 0) && (!bError))
{
EnterCriticalSection (&cs);
sockInfo[nClient].time = time(NULL);
LeaveCriticalSection (&cs);
nLeft = 4;
idx = 0;
curTime = time(NULL);
while(nLeft > 0)
{
ret = send(sockInfo[nClient].sClient, ((char *) &curTime)+idx, nLeft, 0);
if (ret == SOCKET_ERROR)
{
bError = 1;
break;
}
nLeft -= ret;
idx += ret;
}
}//if синхронизация
//приём данных от УВМ
if ((req.typeRequest == 1) && (!bError))
{
EnterCriticalSection (&cs);
sockInfo[nClient].time = time(NULL);
LeaveCriticalSection (&cs);
if (TypeSender < 3)