【发布时间】:2017-05-22 21:10:39
【问题描述】:
我正在开发一个应用程序,它通过 UDP 套接字将客户端的屏幕截图发送到服务器。
由于可以通过 UDP 套接字传输的最大大小为 64KB,所以我在传输之前拆分字节数组。服务端会合并这些字节数组,得到完整的字节数组。
现在我将字节数组转换为 ByteArrayInputStream,然后再转换为 BufferedImage 最后在 JPanel 中显示。
但 BufferedImage 始终为空。
客户代码:
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.*;
import java.util.Arrays;
class UDPClient
{
public static void main(String[] args) throws Exception {
DatagramSocket ds = new DatagramSocket();
InetAddress ip = InetAddress.getByName("127.0.0.1");
DatagramPacket dp;
while (true)
{
BufferedImage img = new Robot().createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(img, "jpeg", baos);
baos.flush();
byte[] buffer = baos.toByteArray();
System.out.println(buffer);
byte[][] dest=splitBytes(buffer, buffer.length / 10);
int len=0;
if (buffer.length%10==0)
len=10;
else
len=11;
byte[] temp=new byte[]{(byte) len};
dp=new DatagramPacket(temp,temp.length,ip,3000);
ds.send(dp);
for (byte[] bytes:dest)
{
dp= new DatagramPacket(bytes,bytes.length, ip, 3000);
ds.send(dp);
}
}
}
public static byte[][] splitBytes(final byte[] data, final int chunkSize)
{
final int length = data.length;
final byte[][] dest = new byte[(length + chunkSize - 1)/chunkSize][];
int destIndex = 0;
int stopIndex = 0;
for (int startIndex = 0; startIndex + chunkSize <= length; startIndex += chunkSize)
{
stopIndex += chunkSize;
dest[destIndex++] = Arrays.copyOfRange(data, startIndex, stopIndex);
}
if (stopIndex < length)
dest[destIndex] = Arrays.copyOfRange(data, stopIndex, length);
return dest;
}
}
服务器代码:
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.List;
class UDPServer extends JPanel
{
static BufferedImage image;
UDPServer() throws IOException {
DatagramSocket ds = null;
try {
ds = new DatagramSocket(3000);
} catch (SocketException e) {
e.printStackTrace();
}
byte[] buf = new byte[1024];
DatagramPacket dp;
JFrame frame=new JFrame("hello");
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
frame.setSize((int)dim.getWidth(),(int)dim.getHeight());
frame.setContentPane(this);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
while (true)
{
dp= new DatagramPacket(buf, 1024);
try {
ds.receive(dp);
} catch (IOException e) {
e.printStackTrace();
}
int len=(int)dp.getData()[0];
List<byte[]> blocks = new ArrayList<>();
for (int i=1;i<=len;i++)
{
blocks.add(dp.getData());
}
byte[] imageData=concatenateByteArrays(blocks);
InputStream bais=new ByteArrayInputStream(imageData);
image=ImageIO.read(bais);
System.out.println(image);
this.repaint();
}
}
public static void main(String[] args) throws Exception {
new UDPServer();
//ds.close();
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawImage(image,0,0,null);
}
public static byte[] concatenateByteArrays(List<byte[]> blocks) {
ByteArrayOutputStream os = new ByteArrayOutputStream();
for (byte[] b : blocks) {
os.write(b, 0, b.length);
}
return os.toByteArray();
}
}
请帮助我。 谢谢你
【问题讨论】:
-
尝试使用调试器响应。跟踪语句?你确定你把非零放在电线上吗?您确定非零值到达服务器吗?有很多地方会出错。您不应该期望我们为您进行调试工作。
-
并且记录在案:不要用这么少的方法做这么多的事情。特别是你的构造函数应该做所有这些事情。
-
是的,我已经调试过了。非零来自客户端到服务器。请帮助。我被击中了。
-
没有什么明显错误...我的提示:将服务器中的“从套接字读取”替换为“从文件读取” - 只是为了看看更简单的方法是否有效。
-
是的,它正在工作。我能够将图像文件转换为缓冲图像并显示它
标签: java swing sockets udp jpanel