运行screenshot类main方法报java.net.SocketException连接重置错误求解
异常原因排查
- 服务端监听逻辑错误:
Listener类的run方法中,每次处理完一个连接就关闭ServerSocket,下次循环才重新创建新的ServerSocket绑定端口。连续发送大量数据时,上一个ServerSocket刚关闭,端口处于TIME_WAIT状态,新的ServerSocket还没完成绑定,此时发送端发起连接会被直接拒绝,导致对端重置连接抛出异常。 writeUTF传输长度超限:DataOutputStream.writeUTF仅支持传输最大长度为65535字节的字符串。你每个数组元素存储了一整行屏幕的像素RGB值,1080P屏幕单条字符串长度轻松超过65535字节,会导致写入异常,接收端主动断开连接。- 空异常吞噬:
its方法中捕获了异常但没有任何打印逻辑,即使截图处理环节出错也无法感知,会把空数组或不完整数据传入发送逻辑,也可能触发传输异常。
可行解决方案
1. 修复服务端监听逻辑
ServerSocket只需初始化一次,循环处理接入的连接,不要每次都销毁重建:
class Listener extends Thread{ ArrayList<Object> queue=new ArrayList<>(); int port; Listener(int port){ this.port=port; } public void run(){ try{ // 只创建一次ServerSocket,不要放在循环内反复生成 ServerSocket ss=new ServerSocket(port); while(true){ Socket s=ss.accept(); DataInputStream dis=new DataInputStream(s.getInputStream()); String str=dis.readUTF(); queue.add(str); // 仅关闭客户端连接,不要关闭ServerSocket s.close(); dis.close(); } }catch(Exception e){ System.out.println("接收环节出错\n "+e); e.printStackTrace(); System.exit(0); } } }
2. 替换传输方案,放弃字符串传像素
直接将截图压缩为JPG/PNG字节数组传输,既避免writeUTF长度限制,也能大幅降低传输数据量:
修改截图方法,直接返回压缩后的字节数组
public static byte[] getScreenBytes() throws Exception{ Robot r=new Robot(); BufferedImage img=r.createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize())); ByteArrayOutputStream baos = new ByteArrayOutputStream(); // 压缩为JPG格式,质量0.8可平衡体积和清晰度 ImageIO.write(img, "jpg", baos); return baos.toByteArray(); }
修改send方法适配字节数组传输
public void send(byte[] data) { try{ Socket s=new Socket(ip,port); DataOutputStream dout=new DataOutputStream(s.getOutputStream()); // 先传数据长度,再传内容,解决粘包问题 dout.writeInt(data.length); dout.write(data); dout.flush(); dout.close(); s.close(); }catch(Exception e){ System.out.println("发送环节出错\n "+e); e.printStackTrace(); System.exit(0); } }
修改接收逻辑读取字节数组
// Listener的run方法对应调整 public void run(){ try{ ServerSocket ss=new ServerSocket(port); while(true){ Socket s=ss.accept(); DataInputStream dis=new DataInputStream(s.getInputStream()); int len = dis.readInt(); byte[] imgData = new byte[len]; dis.readFully(imgData); // 字节数组存入队列,后续可直接转成BufferedImage使用 queue.add(imgData); s.close(); dis.close(); } }catch(Exception e){ System.out.println("接收环节出错\n "+e); e.printStackTrace(); System.exit(0); } }
3. 跨设备传输优化
如果要实现两台电脑无线传输,不要绑定localhost,直接填写目标设备的局域网IP,确保两台设备在同一WiFi下,且防火墙开放对应1111端口。单次传输整张截图比拆成多行传输效率高10倍以上,也能避免大量短连接导致的端口占用问题。
内容的提问来源于stack exchange,提问作者Shadow Strike
相关产品推荐
相关产品推荐

