我已成功使用从C#到Java(Android)的TCP套接字建立了连接。我可以发送和接收字符串消息没问题。但是,当我尝试接收从C#服务器发送的PNG图像时,在Android活动视图上只有黑屏。
基本上,服务器会侦听并等待,直到客户端发送消息为止。服务器收到消息后,将通过向客户端发送图像来响应。
C#服务器:
private void HandleClientComm(object client)
{
TcpClient tcpClient = (TcpClient)client;
NetworkStream clientStream = tcpClient.GetStream();
byte[] message = new byte[4096];
int bytesRead;
while (true)
{
bytesRead = 0;
try
{
//blocks until a client sends a message
bytesRead = clientStream.Read(message, 0, 4096);
}
catch
{
//a socket error has occured
break;
}
if (bytesRead == 0)
{
//the client has disconnected from the server
break;
}
//message has successfully been received. Now let's send an image.
byte[] pic = new byte[5000*1024];
pic = ImageConverter.imageToByteArray(System.Drawing.Image.FromFile("C:\\ic_launcher.png"));
clientStream.Write(pic, 0, pic.Length);
clientStream.Flush();
}
Android客户端:
Socket s = new Socket("192.168.1.154", 8888);
DataInputStream ins = new DataInputStream(s.getInputStream());
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
//Let's send output message
String outMsg = "TCP connecting to " + 8888 + System.getProperty("line.separator");
out.write(outMsg);
out.flush();
//Receive the image from server.
int bytesRead;
byte[] pic = new byte[5000*1024];
bytesRead = ins.read(pic, 0, pic.length);
//Decode the byte array to bitmap and set it on Android ImageView
Bitmap bitmapimage = BitmapFactory.decodeByteArray(pic, 0, bytesRead);
ImageView image = (ImageView) findViewById(R.id.test_image);
image.setImageBitmap(bitmapimage);
//Show in android TextView how much data in bytes has been received (for debugging)
String received;
received= Integer.toString(bytesRead);
test.setText(received);
//close connection
s.close();
现在收到的变量表明已传输了约3000个字节,而图像大小实际上是4.147个字节(在Windows资源管理器中显示),听起来不太正确。
那么,无论如何,为什么图像未显示在Android Activity中?我在这里想念什么?
参考方案
首先。 TCP不发送消息,它发送字节流。您Receive()
的字节流可以包含从消息的一小部分到几条消息的任何内容。不要以为您只会收到一封带有Receive()
的邮件。
您会注意到,如果服务器中进行了适当的错误处理。不要仅仅忽略异常或断开连接。处理它们。
解决问题的最简单方法是发送一个整数标题,该标题说明长度。阅读该标头,然后继续调用Read
,直到传输完整个图像为止。
字符串起作用的原因是该消息很小,并且此后您没有直接传输其他任何信息。因此给您发送消息的错觉。 (尝试彼此直接发送两条消息,Nagle algorithm应该将它们打包在一起,以便您可以在同一Read()
中收到它们)。
我花了两天时间在每个论坛,文档,tuto,博客等上寻找答案。我为实习生启动了一个Android应用程序,因为我不懂Java,所以用xamarin C#开发了它。直到最近一切都还不错,但现在我需要集成一个SDK才能在应用程序中使用POS(销售点),但是该库是用Java编写的,即使跟随文档或辅导老师,我也无法将其与xamarin绑定(我什至无法调试)。这里有人已…
如何在TabLayout中自定义选定的选项卡指示器? - java我想更改带有自定义图标的TabLayout的所选标签指示器,该标签指示器应遵循相同的行为(当用户向下一个标签滑动时,图标将相应移动)。该类中没有默认方法,因为您只能实现选项卡的布局自定义。我决定看一下TabLayout的source code,但1)我无法在类中找到定义制表符指示器绘制时形状的定义的要点,以及2)我找不到甚至完全导入该类。我还希望-如果可能的…
单击后退按钮时,滑行加载的图像会重置 - java我正在滑行加载图像。但是问题是,当我们按下后退按钮时,从视图中清除加载的图像。无论我在活动图像视图中还是在recyclerview中加载图像,我都面临着这个问题。我正在加载图像GlideApp.with(this) .load(url) .into(mToolbarAvatar); 参考方案 在代码中添加两行.skipMemoryCache(true) .d…
有没有一种方法可以在一个mediaplayer对象中播放mp3文件? - java我可以使用Java android中的Mediaplayer类播放声音。我这样制作一个Mediaplayer对象。Mediaplayer mp=Mediaplayer.create(this,R.raw.mysong); 然后开始播放,但是如果我有一首以上的歌曲必须播放。我需要为每个人都做对象吗?我要说的是Mediaplayer类是否具有可以清除旧歌曲并放上…
如果屏幕上显示多个QR码,则扫描QR码 - java我正在开发一个Android示例应用程序作为一个学术项目,需要扫描QR码,我使用了QR扫描代码库,并且如果屏幕上只有一个QR码,我就能成功检测到QR码。是的,我想扫描QR码,尽管一次在屏幕上的多个位置显示相同的QR码。例如,在我的笔记本电脑屏幕上,QR码图像看起来像下面提到的图像。所有QR码都是相同的,它们之间没有区别。考虑以下具有6和4相同QR码但有一些填…