私は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;
}
'IStream' COMオブジェクトを正常に作成していますか?私。 'CreateStreamOnHGlobal'呼び出しは成功しますか? –
受信側で@Someprogrammerdude?私は 'if(CreateStreamOnHGlobal(NULL、true、&istream)== S_OK)'でそれをチェックし、成功しました。 –