Re[2]: Builder + WinAPI send recv select ...
От: Аноним  
Дата: 20.02.03 06:53
Оценка:
Здравствуйте, VVV, Вы писали:

// Главный юнит.
void __fastcall TForm1::GetFileClick(TObject *Sender)
{
        TCPThread *mth=new TCPThread(false,FilStr->Text);
        mth->FreeOnTerminate=true;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
        WSADATA    wData;
    WORD    mVer;
    int    err;

    mVer= MAKEWORD(2,2);
    err=WSAStartup(mVer,&wData);

}



// Юнит потока клиента.
// FILE,TRANSMISSION,END_OF_TRANSMISSION - Дефайны
//s определен в хедере
 
__fastcall TCPThread::TCPThread(bool CreateSuspended,AnsiString FilName)
        : TThread(CreateSuspended)
{
        FileName=FilName;
}
//---------------------------------------------------------------------------
void __fastcall TCPThread::Execute()
{
        int hFile;
        PckHd PacketHead;
    int tmp,iByteRecv,cnt=2048;
    WORD port;
        AnsiString FullFileName,FLen,Abuff,ShortFileName;
        char *buff;
        bool flag=false;
        int iFileLength;
        int iBytesRead,err;
    fd_set rdfds;
    TIMEVAL tm;

    FD_ZERO(&rdfds);

    tm.tv_sec=0;
    tm.tv_usec=0;

        unsigned long adlo;
        BytesRec=0;

    port=6666;

        adlo=inet_addr("127.0.0.1");//Или любой адрес где стоит сервер

        sockaddr_in adr;
    adr.sin_addr.S_un.S_addr=adlo;
    adr.sin_family=AF_INET;
    adr.sin_port=htons(port);

        ShortFileName=FileName;
        int i=ShortFileName.Length();
        while(flag!=true)
        {
                if(ShortFileName.c_str()[i]=='\\')
                {
                        ShortFileName=ShortFileName.Delete(1,i+1);
                        flag=true;
                }
                else
                i--;
        };
        flag=false;

        s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);

          FD_SET(s,&rdfds);

    tmp=connect(s,(sockaddr*)&adr,sizeof(sockaddr_in));
        if(tmp==0)
        {
                PacketHead.CurrPacketSize=FileName.Length()+1;
                PacketHead.Head=FILE;

                buff=(char*)malloc(sizeof(PckHd)+PacketHead.CurrPacketSize);

                memcpy(buff,&PacketHead,sizeof(PckHd));
                memcpy(buff+sizeof(PckHd),FileName.c_str(),PacketHead.CurrPacketSize);

                send(s,buff,sizeof(PckHd)+PacketHead.CurrPacketSize,0);

                free(buff);
                buff=(char*)malloc(sizeof(PckHd)+2048);

                AnsiString Path;
                Path="c:\\"+ShortFileName;//Любой путь куда копировать
                hFile=FileCreate(Path);
                while(flag!=true)
                {
                           if(select(0,&rdfds,NULL,NULL,NULL)>0)//&tm
                        {
                                iByteRecv=recv(s,buff,sizeof(PckHd)+cnt,MSG_PEEK);
                                if(((PckHd*)buff)->Head==TRANSMISSION)
                                {
                                        realloc(buff,sizeof(PckHd)+((PckHd*)buff)->CurrPacketSize);
                                        err=recv(s,buff,sizeof(PckHd)+((PckHd*)buff)->CurrPacketSize,0);
                                        err=FileWrite(hFile,(char*)buff+sizeof(PckHd),((PckHd*)buff)->CurrPacketSize);
                                        BytesRec+=err;
                                        Synchronize(ChangeCap);
                                }
                                else
                                {
                                        if(((PckHd*)buff)->Head==URL)
                                        {
                                                realloc(buff,sizeof(PckHd)+((PckHd*)buff)->CurrPacketSize);
                                                recv(s,buff,sizeof(buff),0);
                                                err=FileWrite(hFile,(char*)buff+sizeof(PckHd),((PckHd*)buff)->CurrPacketSize);
                                                BytesRec+=err;
                                                Synchronize(ChangeCap);
                                        };
                                        if(((PckHd*)buff)->Head==END_OF_TRANSMISSION)
                                        {
                                                realloc(buff,sizeof(PckHd)+((PckHd*)buff)->CurrPacketSize);
                                                recv(s,buff,sizeof(buff),0);
                                                err=FileWrite(hFile,(char*)buff+sizeof(PckHd),((PckHd*)buff)->CurrPacketSize);
                                                BytesRec+=err;
                                                Synchronize(ChangeCap);
                                                FileClose(hFile);
                                                flag=true;
                                        };
                                };
                        };
                };
        };
        closesocket(s);
}
//---------------------------------------------------------------------------
void __fastcall TCPThread::ChangeCap()
{
        Form1->ByRec->Caption=IntToStr(BytesRec);
}


это то что в клиенте в главном и юните потока.

//Главный юнит сервера

void __fastcall TForm1::FormCreate(TObject *Sender)
{
        AccTime->Enabled;
        MsgHst->Clear();
    WSADATA    wData;
    WORD    mVer;
    int    err;
    int     tmp;
    WORD port;

    port=6666;
    mVer= MAKEWORD(2,2);
        sockaddr_in adr;
    adr.sin_addr.S_un.S_addr=INADDR_ANY;
    adr.sin_family=AF_INET;
    adr.sin_port=htons(port);

    err=WSAStartup(mVer,&wData);
    s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    tmp=bind(s,(sockaddr*)&adr,sizeof(sockaddr_in));
    err=listen(s,1);
}
//-------------------------------
void __fastcall TForm1::AccTimeTimer(TObject *Sender)
{
        SOCKET rSock;
    fd_set rdfds;
    TIMEVAL tm;

    FD_ZERO(&rdfds);
    FD_SET(s,&rdfds);

    tm.tv_sec=0;
    tm.tv_usec=0;

    if(select(0,&rdfds,NULL,NULL,&tm)>0)
        {
                sockaddr nadr;
                int dl=sizeof(sockaddr);
                rSock=accept(s,(sockaddr*)&nadr,&dl);//?!sockaddr
                if(rSock!=INVALID_SOCKET)
                {
                        TCPThread *mth = new TCPThread(false,rSock);
                        mth->FreeOnTerminate = true;
                }
        };
}



//Юнит потока процесса sock определен в хедере
__fastcall TCPThread::TCPThread(bool CreateSuspended,SOCKET s)
        : TThread(CreateSuspended)
{
        sock=s;
}
//---------------------------------------------------------------------------
void __fastcall TCPThread::Execute()
{
        bool flag=false;

        PckHd   PacketHead;

        AnsiString  tmpstr;
        int UrlLen;
        int iFileHandle,iByteRecv;
        HANDLE hFile;
        LPVOID hView,pStart;
        int cnt,pOff=0;
        DWORD dwSizeLow,dwSizeHigh;

    int    err;
    int tmp;
    WORD port;

        unsigned long adlo;

    port=6666;

    fd_set rdfds;
    TIMEVAL tm;

    FD_ZERO(&rdfds);
    FD_SET(sock,&rdfds);

    tm.tv_sec=0;
    tm.tv_usec=0;

        UrlName="";FileName="";
        char *buff;
        cnt=2048;
        buff=(char*)malloc(sizeof(PckHd)+cnt);

        while(flag!=true)
        {
                if(select(0,&rdfds,NULL,NULL,&tm)>0)
                {
                        iByteRecv=recv(sock,buff,sizeof(PckHd)+cnt,MSG_PEEK);
                        if(((PckHd*)buff)->Head==FILE)
                        {
                                realloc(buff,sizeof(PckHd)+((PckHd*)buff)->CurrPacketSize);
                                err=recv(sock,buff,sizeof(buff),0);
                                FileName=(char*)buff+sizeof(PckHd);
                                Stat="FileNameRecived: "+FileName;
                                Synchronize(ChangeCap);
                                flag=true;
                        }
                        else
                        {
                                if(((PckHd*)buff)->Head==URL)
                                {
                                        realloc(buff,sizeof(PckHd)+((PckHd*)buff)->CurrPacketSize);
                                        err=recv(sock,buff,sizeof(buff),0);
                                        UrlName=(char*)buff+sizeof(PckHd);
                                        flag=true;
                                };
                        };
                };
        };

        free (buff);

        if(FileName!="")
        {
                iFileHandle = FileOpen(FileName, fmOpenRead);
                dwSizeLow = GetFileSize((HANDLE)iFileHandle, &dwSizeHigh);
                hFile=CreateFileMapping((HANDLE)iFileHandle,NULL,PAGE_READONLY,dwSizeHigh,dwSizeLow,NULL);
                hView=MapViewOfFile(hFile,FILE_MAP_READ,0,0,dwSizeLow);
                Stat="FileMappingSucceed! FileSize: "+IntToStr(dwSizeLow);
                Synchronize(ChangeCap);
                pStart=hView;

                buff=(char*)malloc(sizeof(PckHd)+cnt);

                if(dwSizeLow>2048) cnt=2048;
                else
                {
                        PacketHead.Head=END_OF_TRANSMISSION;
                        PacketHead.CurrPacketSize=dwSizeLow;
                        realloc(buff,sizeof(PckHd)+dwSizeLow);
                        memcpy(buff,&PacketHead,sizeof(PckHd));
                        memcpy(buff+sizeof(PckHd),pStart,dwSizeLow);
                        err=send(sock,buff,sizeof(PckHd)+dwSizeLow,0);
                        BytesSend+=err;
                        Stat="BytesSending...";
                        Synchronize(ChangeCap);
                        flag=false;
                };

                while(flag!=false)
                {
                        if(cnt+pOff<dwSizeLow)
                        {
                                PacketHead.Head=TRANSMISSION;
                                PacketHead.CurrPacketSize=cnt;
                                memcpy(buff,&PacketHead,sizeof(PckHd));
                                memcpy(buff+sizeof(PckHd),(char*)pStart+pOff,cnt);
                                err=send(sock,buff,sizeof(PckHd)+cnt,0);
                                BytesSend+=err;
                                Stat="BytesSending...";
                                Synchronize(ChangeCap);
                                pOff+=cnt;
                        }
                        else
                        {
                                cnt=dwSizeLow-pOff;
                                PacketHead.Head=END_OF_TRANSMISSION;
                                PacketHead.CurrPacketSize=cnt;
                                realloc(buff,sizeof(PckHd)+cnt);
                                memcpy(buff,&PacketHead,sizeof(PckHd));
                                memcpy(buff+sizeof(PckHd),(char*)pStart+pOff,cnt);
                                err=send(sock,buff,sizeof(PckHd)+cnt,0);
                                BytesSend+=err;
                                Stat="BytesSending...";
                                Synchronize(ChangeCap);
                                flag=false;
                        };
                };
                UnmapViewOfFile(hView);
                Stat="Unmaping Success!!!";
                Synchronize(ChangeCap);
        };

}
//---------------------------------------------------------------------------
void __fastcall TCPThread::ChangeCap()
{
        Form1->BySend->Caption=IntToStr(BytesSend);
        Form1->Status->Caption=Stat;
}




Вот собственно и все. Мне кажется это не из-за bind т.к. на XP+98 все работает корректно. А в XP+XP (правда только в тесте участвовали 3 машины XP) может преслать либо некоторое кол-во байт а потом зайти в send и от туда не выйти, может вообще не переслать, а случалось и пересылал весь файл.

ЗЫ: Такое чуйство что в send`е идет блок. Компилятор C++ Builder 6
ЗЗЫ: ПЛЗ!!! =)) Не могли бы вы отправить мне на мыло ваш пример просто из спортивного интереса =) ynblpb@hotbox.ru или ynblpb@freemail.ru
можть и я вам когда-нибудь помогу
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.