2017-03-08 11 views
0

私はwinsock2を通じてサーバー/クライアントを作成しました。クライアントがbmpのスクリーンショットを取得し、jpegに圧縮してサーバに送信します。私が抱えている問題は、サーバーがファイルをディスクに保存する際に問題が発生していることです。データが正しいように受け取らないように。私はそれが私がバッファを送っているか受けているかのやり方でやらなければならないと思う。IStream COMはバッファに読み込み、その後にwinsockを送信します

EDIT:デバッグ中の設定breakpointsから、すべてのデータが受信されたようです。 istream->Writeは、Sizeに対応する正しいバイト数を返し、istream->Seekは、S_OKを返し、CLSID COMオブジェクトには、送信された同じデータが含まれます。また、私はバッファを送信する前に、私はそれが保存するかどうかを確認するためにそれをテストします。それゆえ、私はそれがBufferが送られた、または受け取られた方法でなければならないと仮定しています。

EDIT:両方で バッファがThis

スクリーンショットのように見えるプラスコードを送って終了します。

ScreenShot(Packet_Handler* _Handle) 
{ 
IStream* istream; 
    //char* Buff; 
    HRESULT res = CreateStreamOnHGlobal(NULL, true, &istream); 
    Gdiplus::GdiplusStartupInput gdiInput; 
    ULONG_PTR gdiToken; 
    Gdiplus::GdiplusStartup(&gdiToken, &gdiInput, NULL); 
    { 
     HDC scrdc, memdc; 
     HBITMAP membit; 
     scrdc = ::GetDC(0); 
     int Height = GetSystemMetrics(SM_CYSCREEN); 
     int Width = GetSystemMetrics(SM_CXSCREEN); 
     memdc = CreateCompatibleDC(scrdc); 
     membit = CreateCompatibleBitmap(scrdc, Width, Height); 
     HBITMAP hOldBitmap = (HBITMAP)SelectObject(memdc, membit); 
     BitBlt(memdc, 0, 0, Width, Height, scrdc, 0, 0, SRCCOPY); 

     Gdiplus::Bitmap bitmap(membit, NULL); 
     CLSID clsid; 
     GetEncoderClsid(L"image/jpeg", &clsid); 


     bitmap.Save(istream, &clsid, NULL); 
     bitmap.Save(L"Test.jpeg", &clsid, NULL); //THIS WORKS 
     STATSTG pstatstg = { 0 }; 
     istream->Stat(&pstatstg, 0); 
     ULONG Bytes; 
     char* isBuff = new char[pstatstg.cbSize.QuadPart]; 
     LARGE_INTEGER li; 
     li.QuadPart = 0; 
     istream->Seek(li, STREAM_SEEK_SET, NULL); 
     if (istream->Read(isBuff, pstatstg.cbSize.QuadPart, &Bytes) == S_OK) 
     { 
      IStream* nistream = nullptr; 
      ULONG nBytes; 
      CreateStreamOnHGlobal(NULL, true, &nistream); 
      if (nistream->Write(isBuff, pstatstg.cbSize.QuadPart, &Bytes) == S_OK) 
      { 

       if (nistream->Seek(li, STREAM_SEEK_SET, NULL) == S_OK) 

       { 
        Gdiplus::Bitmap bitmap2(nistream, NULL); 
        bitmap2.Save(L"Testing.jpeg", &clsid, NULL); //THIS WORKS 
       } 
      } 
     } 

     int Size = pstatstg.cbSize.QuadPart; 
     int SOLI = sizeof(ULARGE_INTEGER); 
     int SOCID = sizeof(CLSID); 
     int SOIS = sizeof(IStream); 

     Send_Full_Packet(_Handle, &Size, isBuff, TRUE); 
     Send_Full_Packet(_Handle, &SOCID, &clsid, FALSE); 



     printf("saving Screenshot"); 


     DeleteObject(memdc); 
     DeleteObject(membit); 
     ::ReleaseDC(0, scrdc); 

    } 
    Gdiplus::GdiplusShutdown(gdiToken); 
    _getch(); 
    return 0; 
} 
    void Send_Full_Packet(Packet_Handler* _Handle, int* pSize, void * Buff, bool ispchar) 
    { 
     int SentPackets = 0; 
     int sCheck = 0; 
     int rCheck = 0; 
     int Size = *pSize; 
     char* isBuff;// = new char[Size]; 

      sCheck = send(_Handle->ConnectSocket, (char*)&Size, sizeof(int), NULL); 

     int PacketsSent = 0; 
     sCheck = 0; 
     int PacketsLeft = Size; 
     while (PacketsSent < Size) 
     { 
      if (ispchar == FALSE) 
      { 
       SentPackets = send(_Handle->ConnectSocket, (char*)Buff + PacketsSent, PacketsLeft, NULL); 
      } 
      else { 
       isBuff = (char*)Buff; 
       SentPackets = send(_Handle->ConnectSocket, isBuff + PacketsSent, PacketsLeft, NULL); 
      } 
      if (SentPackets == SOCKET_ERROR) 
      { 
       if (WSAGetLastError() != 10054) 
       { 
        if (WSAGetLastError() == 10035) 
        { 
         SentPackets == 0; 

        } 
        else 
        { 
         printf("Sending Socket error: %d\n", WSAGetLastError()); 
         break; 
        } 

       } 
      } 
      PacketsSent += SentPackets; 
      PacketsLeft -= SentPackets; 
     } 


    } 

は、データが完全に受信するために呼び出すrecv複数必要になることがあり、コード

ScreenShot_Receive_Thread(Packet_Handler* _Handle) 
{ 

    Packet_Handler::_Packet_Type Packet = Packet_Handler::_Packet_Type::Remote; 
    while (true) 
    { 
     if (send(_Handle->si.Connections[_Handle->si.ConnectionCounter - 1], (char*)&Packet, sizeof(Packet_Handler::_Packet_Type), 0) != INVALID_SOCKET) 
     { 
      while (true) 
      { 
       int Size = 0; 
       char* Buff = NULL; 
       Buff = _Handle->Receive_Full_Packet(_Handle, &Size, Buff, TRUE); 
       CLSID clsid; 
       int SOCID = sizeof(CLSID); 
       _Handle->Receive_Full_Packet(_Handle, &SOCID, &clsid, FALSE); 
       IStream* istream = nullptr; 
       ULONG Bytes; 
       CreateStreamOnHGlobal(NULL, true, &istream); 
       if (istream->Write(Buff, Size, &Bytes) == S_OK) 
       { 
        LARGE_INTEGER li; 
        li.QuadPart = 0; 
        if (istream->Seek(li, STREAM_SEEK_SET, NULL) == S_OK) 
        { 
         Gdiplus::Bitmap bitmap(istream, NULL); 
         bitmap.Save(L"Testing.jpeg", &clsid, NULL);//DOESNT WORK 
        } 
       } 

      } 
     } 
    } 
    MessageBox(NULL, L"CLient COnnection Error!", NULL, NULL); 
    return 0; 
} 


    char* Packet_Handler::Receive_Full_Packet(Packet_Handler * _Handle, int* pSize, void * Buff, bool ispchar) 
{ 
    int rCheck = 0; 
    int sCheck = 0; 
    int Size = *pSize; 
    rCheck = recv(_Handle->si.Connections[_Handle->si.ConnectionCounter - 1], (char*)&Size, sizeof(int), 0); 
    if (rCheck == -1) 
    { 
     int Error = WSAGetLastError(); 
     AllocConsole(); 
     freopen("CONOUT$", "w", stdout); 
     std::cout << "The Error is: " << Error << std::endl; 
    } 
    *pSize = Size; 
    char* isBuff;// = NULL; 
    int PacketsReceived = 0; 
    int PacketsLeft = Size; 
    int ReceivedPackets = 0; 
    while (PacketsReceived < Size) 
    { 
     if (ispchar == FALSE) 
     { 
      ReceivedPackets = recv(_Handle->si.Connections[_Handle->si.ConnectionCounter - 1], (char*)Buff + PacketsReceived, PacketsLeft, 0); 

     } 
     else 
     { 
      isBuff = new char[Size]; //I Think my problem is here// 

      ReceivedPackets = recv(_Handle->si.Connections[_Handle->si.ConnectionCounter - 1], isBuff + PacketsReceived, PacketsLeft, 0); 

     } 
     if (ReceivedPackets == SOCKET_ERROR) 
     { 
      int Error = WSAGetLastError(); 
      if (Error != 10054) 
      { 
       if (Error == 10035 || Error == 6) 
       { 
        ReceivedPackets == 0; 
       } 
       else 
       { 
        AllocConsole(); 
        freopen("CONOUT$", "w", stdout); 
        std::cout << "The Error is: " << Error << std::endl; 
        //MessageBox(NULL, (WCHAR*)WSAGetLastError(), NULL, NULL); 
        _getch(); 
        //return NULL; 
        break; 
       } 
      } 
     } 

     PacketsReceived += ReceivedPackets; 
     PacketsLeft -= ReceivedPackets; 
    } 
    return isBuff; 
} 
+0

'IStream' COMオブジェクトを正常に作成していますか?私。 'CreateStreamOnHGlobal'呼び出しは成功しますか? –

+0

受信側で@Someprogrammerdude?私は 'if(CreateStreamOnHGlobal(NULL、true、&istream)== S_OK)'でそれをチェックし、成功しました。 –

答えて

0

最後にそれを解説します。私がバッファを送っていたやり方には何も間違いがないことが分かった。実際にはCLSIDでした。私は受信側にGetEncoderClsid機能を置くことになった。バターのように働く。

0

を受信します。これが起こると、Receive_Full_Packetはそのような呼び出しのたびに新しいバッファを割り当て、すぐにそれらの1つを除くすべてのバッファをリークします。呼び出し元に返すのは最後の割り当てです。ほとんどの場合、ランダムなガーベッジでいっぱいになっているバッファですが、その最後に最後のデータがあります。

ループの外側にisBuff = new char[Size];行を移動するには、サイズを取得した最初のrecvコールの直後に配置します。

+0

私はそれを試みます。しかし今のところ私は自分のローカルアドレス '127.0.0.1'を聞いているので、一度にフルバッファを送ります。 –

+0

それはそれではありませんでしたが、ありがとうございました。完全なパケットを送信しなかった場合、アプリケーションに大きな影響を与えます。 –

関連する問題