Смекни!
smekni.com

Розробка програмного забезпечення системи збору даних про хід та параметри технологічного процесу (стр. 4 из 5)

nLeft = sizeof(package1);

else

nLeft = sizeof(package2);

idx = 0;

while(nLeft > 0)

{

if (TypeSender < 3)

ret = recv(sockInfo[nClient].sClient, ((char *)&pack1)+idx, nLeft, 0);

else

ret = recv(sockInfo[nClient].sClient, ((char *)&pack2)+idx, nLeft, 0);

if ((ret == SOCKET_ERROR)||(ret == 0))

{

bError = 1;

break;

}

nLeft -= ret;

idx += ret;

}//while

//запись полученных данных в файл

if (!bError)

if (TypeSender < 3)

{

EnterCriticalSection (&csFile);

if (pack1.time >= lastTimeGroup1)

{

lastTimeGroup1 = pack1.time;

fwrite((void *)&pack1,sizeof(package1) ,1,f1);

fflush(f1);

}

LeaveCriticalSection (&csFile);

}

else //TypeSender > 3

{

EnterCriticalSection (&csFile);

if (pack2.time >= lastTimeGroup2)

{

lastTimeGroup2 = pack2.time;

fwrite((void *)&pack2,sizeof(package2) ,1,f2);

fflush(f2);

}

LeaveCriticalSection (&csFile);

}

}//if УВМ

//работа с рабочей станцией

if ((req.typeRequest == 2) && (!bError))

{

//сохранение времени последнего обращения

EnterCriticalSection (&cs);

sockInfo[nClient].time = time(NULL);

LeaveCriticalSection (&cs);

//приём диапазона и типа УВМ

nLeft = sizeof (requestRange);

idx = 0;

while(nLeft > 0)

{

ret = recv(sockInfo[nClient].sClient, ((char *)&reqRange)+idx, nLeft, 0);

if ((ret == SOCKET_ERROR)||(ret == 0))

{

bError = 1;

break;

}

nLeft -= ret;

idx += ret;

}//while

//поиск кол-ва файлов удовлетворяющих диапазону времени

packServ.typeRequest = 3; //данные от сервера

packServ.typeSender = 6; //сервер

packServ.lengthPack = sizeof (packageServer);

packServ.AmountPacks = 0;

EnterCriticalSection (&csFile);

if (reqRange.iTypeUVM == 1)

{

curPos = ftell(f1);

fseek(f1, 0, SEEK_END);

endPos = ftell(f1);

fseek(f1, 0, SEEK_SET);

nStructs = endPos / (sizeof(package1));

iFound = 0;

for (i = 0; i<nStructs; i++)

{

fread((void *)&pack1, sizeof(package1), 1, f1);

if ((pack1.time >=reqRange.tBegin) && ( pack1.time <= reqRange.tEnd))

{

packServ.AmountPacks++;

if (iFound == 0)

{

iFound = 1;

startPos = ftell(f1) - sizeof(package1);

}

}

}//for

fseek(f1, curPos, SEEK_SET);

}

else

{

curPos = ftell(f2);

fseek(f2, 0, SEEK_END);

endPos = ftell(f2);

fseek(f2, 0, SEEK_SET);

nStructs = endPos / (sizeof(package2));

iFound = 0;

for (i = 0; i<nStructs; i++)

{

fread((void *)&pack2, sizeof(package2), 1, f2);

if ((pack2.time >=reqRange.tBegin) && ( pack2.time <= reqRange.tEnd))

{

packServ.AmountPacks++;

if (iFound == 0)

{

iFound = 1;

startPos = ftell(f2) - sizeof(package2);

}

}

}//for

fseek(f2, curPos, SEEK_SET);

}

LeaveCriticalSection (&csFile);

//отсылка количества найденных структур

nLeft = packServ.lengthPack;

idx = 0;

while(nLeft > 0)

{

ret = send(sockInfo[nClient].sClient, ((char *) &packServ)+idx, nLeft, 0);

if (ret == SOCKET_ERROR)

{

bError = 1;

break;

}

nLeft -= ret;

idx += ret;

}

//считывание структур из файлов

if ((iFound != 0)&&(!bError))

{

EnterCriticalSection (&csFile);

if (reqRange.iTypeUVM == 1)

{

pack1Array = new package1[packServ.AmountPacks];

curPos = ftell(f1);

fseek(f1, startPos, SEEK_SET);

for (i = 0; i<packServ.AmountPacks; i++)

fread((void *)&pack1Array[i], sizeof(package1), 1, f1);

fseek(f1, curPos, SEEK_SET);

}

else

{

pack2Array = new package2[packServ.AmountPacks];

curPos = ftell(f2);

fseek(f2, startPos, SEEK_SET);

for (i = 0; i<packServ.AmountPacks; i++)

fread((void *)&pack2Array[i], sizeof(package2), 1, f2);

fseek(f2, curPos, SEEK_SET);

}

LeaveCriticalSection (&csFile);

//отсылка структур

for (i = 0; i<packServ.AmountPacks; i++)

{

if (reqRange.iTypeUVM == 1)

nLeft = sizeof(package1);

else

nLeft = sizeof(package2);

idx = 0;

while(nLeft > 0)

{

if (reqRange.iTypeUVM == 1)

ret = send(sockInfo[nClient].sClient, ((char *) &pack1Array[i])+idx, nLeft, 0);

else

ret = send(sockInfo[nClient].sClient, ((char *) &pack2Array[i])+idx, nLeft, 0);

if (ret == SOCKET_ERROR)

{

bError = 1;

break;

}

nLeft -= ret;

idx += ret;

}//while

if (bError == 1)

{

idx = 5;

break;

}

}//for

if (reqRange.iTypeUVM == 1)

delete[] pack1Array;

else

delete[] pack2Array;

}//if iFound

}//if PC

}//while (!bError)

//удаление записи о скруктуре текущего сокете

if (!bAlowCloseClient[nClient])

{

EnterCriticalSection (&cs);

DeleteSockInfo (nClient, 0);

LeaveCriticalSection (&cs);

}

return 0;

}//ClientThread

//---------------------------------------------------------------------------

unsigned __stdcall AcceptThread(LPVOID lpParam)

{

SOCKET sockAccept;

UINT iThreadId;

while (1)

{

sockAccept = accept(sListen, NULL, NULL);

if ((sockAccept == INVALID_SOCKET) && (WSAGetLastError() == WSAENOTSOCK))

break;

EnterCriticalSection (&cs);

if ((sockAccept != INVALID_SOCKET) && (iNumClients < MAX_CLIENT ))

{

sockInfo[iNumClients].sClient = sockAccept;

sockInfo[iNumClients].typeSender = 0;

sockInfo[iNumClients].time = time(NULL);

sockInfo[iNumClients].hClientThread =(HANDLE) _beginthreadex(NULL, 0,

ClientThread, (LPVOID)iNumClients, 0, &iThreadId);

sockInfo[iNumClients].time = time(NULL);

iNumClients ++ ;

LeaveCriticalSection (&cs);

}

else

{

LeaveCriticalSection (&cs);

shutdown(sockAccept, SD_BOTH);

closesocket(sockAccept);

}

}

return 0;

} // AcceptThread()

//---------------------------------------------------------------------------

unsigned __stdcall ControlThread(LPVOID lpParam)

{

int i;

DWORD dwWaitState;

while (1)

{

dwWaitState = WaitForSingleObject(hEvent, timeToSleep);

if (dwWaitState == WAIT_OBJECT_0)

break;

EnterCriticalSection (&cs);

for (i = 0; i< iNumClients; i++)

{

if ((sockInfo[i].typeSender == 5) || (sockInfo[i].typeSender == 0))

{

if ((time(NULL) - sockInfo[i].time)>600)

{

DeleteSockInfo(i , 1);

}

}

else

{

if ((time(NULL) - sockInfo[i].time)>60)

{

DeleteSockInfo(i , 1);

}

}

}//for

LeaveCriticalSection (&cs);

}//while

return 0;

} // ControlThread()

//---------------------------------------------------------------------------

__fastcall TForm1::TForm1(TComponent* Owner)

: TForm(Owner)

{

}

//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)

{

struct sockaddr_in server;

UINT iThreadId;

AnsiString sAddress, sPort;

char * cAddress, * cPort;

unsigned int lenAdr, lenPort, iPort;

Form1->Button1->Enabled = FALSE;

//создание или открытие файлов

hEvent = CreateEvent( NULL, FALSE, FALSE, NULL);

if ((f1=fopen("group1.txt","a+b"))==NULL)

{

Form1->Button1->Enabled = TRUE;

return;

}

fseek (f1, 0, SEEK_END);

if ((f2=fopen("group2.txt","a+b"))==NULL)

{

fclose(f1);

Form1->Button1->Enabled = TRUE;

return;

}

fseek (f2, 0, SEEK_END);

if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)

{

fclose(f1);

fclose(f2);

Form1->Button1->Enabled = TRUE;

return;

}

//создание необходимых событий, секций

hEvent = CreateEvent( NULL, FALSE, FALSE, NULL);

InitializeCriticalSection (&cs);

InitializeCriticalSection (&csFile);

//создание сокета

sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

if (sListen == INVALID_SOCKET)

{

CloseHandle (hEvent);

fclose(f1);

fclose(f2);

DeleteCriticalSection (&cs);

DeleteCriticalSection (&csFile);

Form1->Button1->Enabled = TRUE;

return;

}

// преобразование адреса

sAddress = Form1->Edit2->Text;

cAddress = sAddress.c_str();

lenAdr = sAddress.Length();

cAddress[lenAdr] = '&bsol;0';

//преобразование порта

sPort = Form1->Edit3->Text;

cPort = sPort.c_str();

lenPort = sPort.Length();

cPort[lenPort] = '&bsol;0';

iPort = atoi(cPort);

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)

{

CloseHandle (hEvent);

shutdown(sListen, SD_BOTH);

closesocket(sListen);

fclose(f1);

fclose(f2);

DeleteCriticalSection (&cs);

DeleteCriticalSection (&csFile);

Form1->Button1->Enabled = TRUE;

return;

}

if (bind(sListen, (SOCKADDR*) &server, sizeof(server)) == SOCKET_ERROR)

{

CloseHandle (hEvent);

shutdown(sListen, SD_BOTH);

closesocket(sListen);

fclose(f1);

fclose(f2);

DeleteCriticalSection (&cs);

DeleteCriticalSection (&csFile);

Form1->Button1->Enabled = TRUE;

return;

}

if (listen(sListen, 8) == SOCKET_ERROR)

{

CloseHandle (hEvent);

shutdown(sListen, SD_BOTH);

closesocket(sListen);

fclose(f1);

fclose(f2);

DeleteCriticalSection (&cs);

DeleteCriticalSection (&csFile);

Form1->Button1->Enabled = TRUE;

return;

}

//создание потока accept

hThreadAccept = (HANDLE)_beginthreadex(NULL, 0, AcceptThread, (LPVOID)sListen, 0,

&iThreadId);

if (hThreadAccept == NULL)

{

CloseHandle (hEvent);

shutdown(sListen, SD_BOTH);

closesocket(sListen);

fclose(f1);

fclose(f2);

DeleteCriticalSection (&cs);

DeleteCriticalSection (&csFile);

Form1->Button1->Enabled = TRUE;

return;

}

//создание потока отслеживания времени последнего обращени клиентов

hThreadControl = (HANDLE)_beginthreadex(NULL, 0, ControlThread, (LPVOID)sListen, 0,

&iThreadId);

if (hThreadControl == NULL)

{

return;

}

bServWorking = TRUE;

return;

}

//---------------------------------------------------------------------------

void DeleteSockInfo(int num, uc bWaitThread)

{

int i;

bAlowCloseClient[num] = 1;

shutdown(sockInfo[num].sClient, SD_BOTH);

closesocket(sockInfo[num].sClient);

if (bWaitThread)

WaitForSingleObject(sockInfo[num].hClientThread, INFINITE);

CloseHandle (sockInfo[num].hClientThread);

bAlowCloseClient[num] = 0;

for (i = num; i<(iNumClients-1); i++)

sockInfo[i] = sockInfo[i+1];

iNumClients--;

}

//---------------------------------------------------------------------------

void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)

{

int i;

if (!bServWorking)

return;

// Закрытие потока Control и события ожидания

SetEvent (hEvent);

WaitForSingleObject(hThreadControl, INFINITE);

CloseHandle (hThreadControl);

CloseHandle (hEvent);

//закрытие сокета сервера и потока Accept

shutdown(sListen, SD_BOTH);

closesocket(sListen);

WaitForSingleObject(hThreadAccept, INFINITE);

CloseHandle (hThreadAccept);

//закрытие сокетов клиентов -> закрытие потоков

EnterCriticalSection (&cs);

for (i = 0; i<iNumClients; i++)

{

bAlowCloseClient[i] = 1;

shutdown(sockInfo[i].sClient, SD_BOTH);

closesocket(sockInfo[i].sClient);

WaitForSingleObject(sockInfo[i].hClientThread, INFINITE);

CloseHandle (sockInfo[i].hClientThread);

}

LeaveCriticalSection (&cs);

fclose(f1);

fclose(f2);

DeleteCriticalSection (&cs);

DeleteCriticalSection (&csFile);

WSACleanup();

}

Додаток В. Вихідний текст робочої станції

//---------------------------------------------------------------------------

#include <vcl.h>

#pragma hdrstop

#include "Client.h"

#include <time.h>

#include <winsock2.h>

//---------------------------------------------------------------------------

#pragma package(smart_init)

#pragma resource "*.dfm"

TForm1 *Form1;

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

{

uc typeRequest;

uc typeSender;

uc lengthPack;

ui iTypeUVM;

time_t tBegin;

time_t tEnd;

} requestRange;

typedef struct

{

uc typeRequest;

uc typeSender;

uc lengthPack;

unsigned long AmountPacks;

} packageServer;

#pragma pack (pop)

SOCKET sClient;

WSADATA wsd;

//---------------------------------------------------------------------------

void CloseClientSocket()

{

Form1->Button2->Enabled = FALSE;

Form1->Button3->Enabled = FALSE;

shutdown(sClient, SD_BOTH);

closesocket(sClient);

Form1->Button1->Enabled = TRUE;

}

//---------------------------------------------------------------------------

__fastcall TForm1::TForm1(TComponent* Owner)

: TForm(Owner)

{

StringGrid1->RowCount = 2;

StringGrid1->Rows[1]->Clear();

StringGrid1->Cells[0][0] = "№";

StringGrid1->Cells[1][0] = "Год";

StringGrid1->Cells[2][0] = "Месяц";

StringGrid1->Cells[3][0] = "День месяца";

StringGrid1->Cells[4][0] = "Часы";

StringGrid1->Cells[5][0] = "Минуты";

StringGrid1->Cells[6][0] = "Секунды";

}

//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)

{

struct sockaddr_in server;

AnsiString sAddress, sPort;

char * cAddress, * cPort;

unsigned int lenAdr, lenPort, iPort;

int nLeft, idx, ret;

request req;

time_t UpdateTime;

Form1->Button1->Enabled = FALSE;

// преобразование адреса

sAddress = Form1->Edit1->Text;

cAddress = sAddress.c_str();

lenAdr = sAddress.Length();

cAddress[lenAdr] = '&bsol;0';

//преобразование порта

sPort = Form1->Edit2->Text;

cPort = sPort.c_str();

lenPort = sPort.Length();

cPort[lenPort] = '&bsol;0';

iPort = atoi(cPort);

if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)

{