Transmitting/receiving 带有 .NET 套接字 C++/CLI 的位图
Transmitting/receiving a bitmap with .NET Sockets C++/CLI
我正在为我的 Schoolproject 编写一个基于 Internet/Multiplayer 的绘画游戏。
所以现在我需要编写一个 PictureBox,它始终适用于服务器。
首先,我使用的是 .net TCP 客户端和监听器,它已经可以工作了(我正在发送和接收一些字符串)。我有 2 个静态 类 代表服务器和客户端。
我的基本想法是将来自 PictureBox 的 bmp 转换为 Byte[] 通过 NetworkStream 使用 BinaryReader 传输它。
在另一端,接收到的 Byte[] 将被转换回 bmp 并进入 PictureBox。
这是我的两个函数:
void Server::sendBMP(Bitmap^ bmp){
array<Byte>^bytes = gcnew array<Byte>(256);
BinaryWriter^ bw = gcnew BinaryWriter(stream);
MemoryStream^ ms = gcnew MemoryStream();
bmp->Save(ms,System::Drawing::Imaging::ImageFormat::Bmp); //Conversion from BMP to Byte[]
bytes = ms->ToArray();
bw->Write(bytes);}
Bitmap^ Server::receiveBMP(void){
array<Byte>^buffer = gcnew array<Byte>(10000);
BinaryReader^ br = gcnew BinaryReader(stream);
Bitmap^ bmp = gcnew Bitmap(1500,612);
buffer = br->ReadBytes(10000);
MemoryStream^ ms = gcnew MemoryStream(buffer); // Conversion From Byte[] to BMP
bmp->FromStream(ms);
return bmp;}
我总是收到 "System.ArgumentException" 错误。
我正在使用同步 TCP 套接字。这是我这样做的正确方式吗?
堆栈跟踪:
Server::receiveBMP() line 105 + 0x8 Bytes
DrawMyThing::MyForm::streamIMG() line 2774 + 0x6 Bytes
第 105 行:
bmp->FromStream(ms); //From my Server::receiveIMG()
第 2774 行:
private: static void streamIMG(void){
while(1){
if(status==1){ //If Server
bitmap = Server::receiveBMP(); //line 2774
}else{
Client::sendBMP(bitmap);
}
}
}
顺便说一句,我将此 streamIMG 函数作为线程调用:
Thread^ imgstreamthread = gcnew Thread(gcnew ThreadStart(MyForm::streamIMG));
imgstreamthread->Start();
buffer = br->ReadBytes(10000);
您的代码中的错误在这里。在这里写 10000 应该会让你 有点 不舒服。你是怎么想出来的?为什么不是20000?编写代码时切勿使用 "magic number"。这几乎总是会产生错误。
那你写什么呢?它不能太大,电话会挂起。它不能太小,您将无法在位图中读取足够的字节,并且您发现程序将失败。它必须是位图中 精确 的字节数。
这是先有鸡还是先有蛋的问题,你怎么知道的?你不知道,发射器必须提供帮助。它必须先发送尺寸:
void Server::sendBMP(Bitmap^ bmp){
//...
bytes = ms->ToArray();
bw->Write(bytes->Length);
bw->Write(bytes);
}
现在很简单:
Bitmap^ Server::receiveBMP(void) {
BinaryReader^ br = gcnew BinaryReader(stream);
int length = br->ReadInt32();
array<Byte>^ buffer = br->ReadBytes(length);
System::Diagnostics::Debug::Assert(buffer->Length == length);
MemoryStream^ ms = gcnew MemoryStream(buffer);
return safe_cast<Bitmap^>(Image::FromStream(ms));
}
我正在为我的 Schoolproject 编写一个基于 Internet/Multiplayer 的绘画游戏。 所以现在我需要编写一个 PictureBox,它始终适用于服务器。
首先,我使用的是 .net TCP 客户端和监听器,它已经可以工作了(我正在发送和接收一些字符串)。我有 2 个静态 类 代表服务器和客户端。
我的基本想法是将来自 PictureBox 的 bmp 转换为 Byte[] 通过 NetworkStream 使用 BinaryReader 传输它。
在另一端,接收到的 Byte[] 将被转换回 bmp 并进入 PictureBox。
这是我的两个函数:
void Server::sendBMP(Bitmap^ bmp){
array<Byte>^bytes = gcnew array<Byte>(256);
BinaryWriter^ bw = gcnew BinaryWriter(stream);
MemoryStream^ ms = gcnew MemoryStream();
bmp->Save(ms,System::Drawing::Imaging::ImageFormat::Bmp); //Conversion from BMP to Byte[]
bytes = ms->ToArray();
bw->Write(bytes);}
Bitmap^ Server::receiveBMP(void){
array<Byte>^buffer = gcnew array<Byte>(10000);
BinaryReader^ br = gcnew BinaryReader(stream);
Bitmap^ bmp = gcnew Bitmap(1500,612);
buffer = br->ReadBytes(10000);
MemoryStream^ ms = gcnew MemoryStream(buffer); // Conversion From Byte[] to BMP
bmp->FromStream(ms);
return bmp;}
我总是收到 "System.ArgumentException" 错误。
我正在使用同步 TCP 套接字。这是我这样做的正确方式吗?
堆栈跟踪:
Server::receiveBMP() line 105 + 0x8 Bytes
DrawMyThing::MyForm::streamIMG() line 2774 + 0x6 Bytes
第 105 行:
bmp->FromStream(ms); //From my Server::receiveIMG()
第 2774 行:
private: static void streamIMG(void){
while(1){
if(status==1){ //If Server
bitmap = Server::receiveBMP(); //line 2774
}else{
Client::sendBMP(bitmap);
}
}
}
顺便说一句,我将此 streamIMG 函数作为线程调用:
Thread^ imgstreamthread = gcnew Thread(gcnew ThreadStart(MyForm::streamIMG));
imgstreamthread->Start();
buffer = br->ReadBytes(10000);
您的代码中的错误在这里。在这里写 10000 应该会让你 有点 不舒服。你是怎么想出来的?为什么不是20000?编写代码时切勿使用 "magic number"。这几乎总是会产生错误。
那你写什么呢?它不能太大,电话会挂起。它不能太小,您将无法在位图中读取足够的字节,并且您发现程序将失败。它必须是位图中 精确 的字节数。
这是先有鸡还是先有蛋的问题,你怎么知道的?你不知道,发射器必须提供帮助。它必须先发送尺寸:
void Server::sendBMP(Bitmap^ bmp){
//...
bytes = ms->ToArray();
bw->Write(bytes->Length);
bw->Write(bytes);
}
现在很简单:
Bitmap^ Server::receiveBMP(void) {
BinaryReader^ br = gcnew BinaryReader(stream);
int length = br->ReadInt32();
array<Byte>^ buffer = br->ReadBytes(length);
System::Diagnostics::Debug::Assert(buffer->Length == length);
MemoryStream^ ms = gcnew MemoryStream(buffer);
return safe_cast<Bitmap^>(Image::FromStream(ms));
}