//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include <stdio.h>
#include <dir.h>
#include <io.h>
#include "Transmit.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
__fastcall TTranThread::TTranThread(TRANSPARASTRUC TranPara, bool CreateSuspended)
: TThread(CreateSuspended)
{
mTranPara.DataPath = TranPara.DataPath.Trim();
mTranPara.ImgPath = TranPara.ImgPath.Trim();
mTranPara.SocketSrv_Ip = TranPara.SocketSrv_Ip.Trim();
mTranPara.SocketSrv_Port = TranPara.SocketSrv_Port;
mTranPara.MsgHandle = TranPara.MsgHandle;
mTranPara.TransFileType = TranPara.TransFileType;
if (!CreateSuspended)
{
Resume();
}
}
//---------------------------------------------------------------------------
__fastcall TTranThread::~TTranThread(void)
{
WSACleanup(); //释放动态库ws2_32.dll
}
//---------------------------------------------------------------------------
void __fastcall TTranThread::Execute()
{
AnsiString mFileName; //FindFile函数查找到的文件名称
WSADATA wsaData; //动态库初始化数据结构 MAKEWORD(2,2) 2.2版本
int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );
if ( iResult != NO_ERROR )
{
//用WSAStartup 保证加载ws2_32.dll
if(mTranPara.MsgHandle!=NULL) SendMessage(mTranPara.MsgHandle,WM_SETTEXT,0,((LPARAM)"加载ws2_32.dll错误"));
return;
}
while(!Terminated)
{
Sleep(1);
if(mTranPara.MsgHandle!=NULL) SendMessage(mTranPara.MsgHandle,WM_SETTEXT,0,((LPARAM)"查找*.DBK文件并传输"));
//若文件类型改为*.* 则可传输任何类型的文件
//查找JPG文件并传输
mFileName=FindFile(mTranPara.DataPath,"*.DBK");//mTranPara.TransFileType );
if(!mFileName.IsEmpty())
{
Delay(30);//必须的,保证其他线程有足够的时间写文件,防止文件读写冲突 延长的时间长短可调整
SendFile(mTranPara.DataPath,mFileName,1);
}
if(mTranPara.MsgHandle!=NULL) SendMessage(mTranPara.MsgHandle,WM_SETTEXT,0,((LPARAM)"查找*.LBK文件并传输"));
mFileName=FindFile(mTranPara.DataPath,"*.LBK");//mTranPara.TransFileType );
if(!mFileName.IsEmpty())
{
Delay(30);//必须的,保证其他线程有足够的时间写文件,防止文件读写冲突 延长的时间长短可调整
SendFile(mTranPara.DataPath,mFileName,2);
}
if(mTranPara.MsgHandle!=NULL) SendMessage(mTranPara.MsgHandle,WM_SETTEXT,0,((LPARAM)"查找*.IMG文件并传输"));
mFileName=FindFile(mTranPara.ImgPath,"*.IMG");//mTranPara.TransFileType );
if(!mFileName.IsEmpty())
{
Delay(30);//必须的,保证其他线程有足够的时间写文件,防止文件读写冲突 延长的时间长短可调整
SendFile(mTranPara.ImgPath,mFileName,3);
}
if(mTranPara.MsgHandle!=NULL) SendMessage(mTranPara.MsgHandle,WM_SETTEXT,0,((LPARAM)"查找*.JPG文件并传输"));
mFileName=FindFile(mTranPara.ImgPath,"*.JPG");//mTranPara.TransFileType );
if(!mFileName.IsEmpty())
{
Delay(50);//必须的,保证其他线程有足够的时间写文件,防止文件读写冲突 延长的时间长短可调整
SendFile(mTranPara.ImgPath,mFileName,4);
}
}
}
//---------------------------------------------------------------------------
/*
函数名称:AnsiString __fastcall TTranThread::FindFile(AnsiString sFilePath,AnsiString sFileName)
参数: AnsiString sFilePath 指定查找的目录
AnsiString sFileName 指定查找的文件类型 *.jpg
返回值: AnsiString 文件名称
函数功能:查找文件是否存在,如果存在则返回该文件名称
*/
AnsiString __fastcall TTranThread::FindFile(AnsiString sFilePath,AnsiString sFileName)
{
AnsiString sFile; //完整的绝对路径+文件类型
AnsiString RetFileName; //返回的文件名称
struct ffblk ffblk;
int done;
sFile = sFilePath + sFileName;
done=-1;
done = findfirst(sFile.c_str(),&ffblk,0);
RetFileName="";
if(done==0) RetFileName=ffblk.ff_name;
return RetFileName;
}
//---------------------------------------------------------------------------
/*
函数名称:void __fastcall TTranThread::SendFile(AnsiString sFilePath,AnsiString sFileName,int fType)
参数: AnsiString sFilePath 指定发送文件所在的目录
AnsiString sFileName 带发送文件名称
int fType 发送的文件类型 自己定义的 1-dbk文件 2-lbk文件 3-jpg文件 4-img文件 5.....预留
返回值: 无
函数功能:发送文件
*/
void __fastcall TTranThread::SendFile(AnsiString sFilePath,AnsiString sFileName,int fType)
{
AnsiString sSendFileName;
sSendFileName= sFilePath + sFileName;
int mFileType;
mFileType=fType;
try
{
//建立socket socket
SOCKET sockSrv;
sockSrv = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
if ( sockSrv == INVALID_SOCKET )
{
if(mTranPara.MsgHandle!=NULL) SendMessage(mTranPara.MsgHandle,WM_SETTEXT,0,((LPARAM)"建立socket失败"));
return ;
}
//地址结构
sockaddr_in clientService ;
clientService.sin_family = AF_INET;
clientService.sin_addr.s_addr = inet_addr(mTranPara.SocketSrv_Ip.c_str());
clientService.sin_port = htons( mTranPara.SocketSrv_Port);
//连接到服务器 阻塞方式
if ( connect(sockSrv, (SOCKADDR*) &clientService, sizeof(clientService) ) == SOCKET_ERROR)
{
if(mTranPara.MsgHandle!=NULL) SendMessage(mTranPara.MsgHandle,WM_SETTEXT,0,((LPARAM)"连接失败"));
return ;
}
else
{
if(mTranPara.MsgHandle!=NULL) SendMessage(mTranPara.MsgHandle,WM_SETTEXT,0,((LPARAM)"连接成功"));
}
//文件发包协议 文件类型 1byte + 文件名称 32byte + 文件长度 12byte 用字符串方式表示
//文件类型1-dbk文件 2-lbk文件 3-jpg文件 4-img文件 5.....预留
//回应数据包中 0-错误
char sendbuf[SEND_BUFFER_SIZE+PROTOCAL_HEAD_LEN];
DWORD dwRead; //文件大小
BOOL bRet;
bool FirstSendFlag;//第一个包发标记
DWORD dwSendFile;
FILE *fp;
DWORD fSize;
dwSendFile=0;
fSize=0;
memset(sendbuf,'\0',sizeof(sendbuf));
sendbuf[0]=mFileType;
sprintf(&sendbuf[1],"%s",sFileName);
//获取文件大小 必须要先打开文件才能取到
fp = fopen(sSendFileName.c_str(),"rb");
if (fp == NULL)
{
fclose(fp);
closesocket(sockSrv);
return ;
}
fSize = filelength(fileno(fp)); //GetFileSize函数也可以取到文件长度
fclose(fp);
sprintf(&sendbuf[33],"%s",AnsiString(fSize+PROTOCAL_HEAD_LEN)); //包的总长度需要加PROTOCAL_HEAD_LEN个byte
HANDLE hFile=CreateFile(sSendFileName.c_str(),GENERIC_READ,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
FirstSendFlag=false;
while(1) //因为文件如果比较大不能一次发完,需要分批发送
{
if(FirstSendFlag==false) //第一个包要多发PROTOCAL_HEAD_LENbyte,因为包含着包的头信息
bRet=ReadFile(hFile,&sendbuf[PROTOCAL_HEAD_LEN],SEND_BUFFER_SIZE,&dwRead,NULL);
else
bRet=ReadFile(hFile,&sendbuf[0],SEND_BUFFER_SIZE,&dwRead,NULL);
dwSendFile+=dwRead;
if(bRet==FALSE||&dwRead==0)
{
if(mTranPara.MsgHandle!=NULL) SendMessage(mTranPara.MsgHandle,WM_SETTEXT,0,((LPARAM)"读取失败"));
if(hFile!=NULL) CloseHandle(hFile);
closesocket(sockSrv);
return;
}
else if(dwRead==0 || dwSendFile==fSize+PROTOCAL_HEAD_LEN)
{
if(mTranPara.MsgHandle!=NULL) SendMessage(mTranPara.MsgHandle,WM_SETTEXT,0,((LPARAM)"文件发送成�