这次实现的功能,主要是使用base64对所选择的文件进行编码,然后通过UDP群发出去。线程Image_recive对接收到的base64编码的数据进行解码。然后缓存到本地。发送的图片的一瞬间,并且还发送了一个信息,告诉别人这个图片是我分享的,这个时候,其他人可以点击预览图片,去预览这个图片。
一共使用了两个socket,第一个socket是专门用来发送和接收消息的。第二个socket是专门用来收发图片的。socket使用的端口是6760,socket2使用的端口是6770。
下面的代码中就使用了两个socket,第一个socket是聊天用的,第二个socket是发图片用的。避免冲突。
1 /*发送图片按钮事件*/ 2 public void btnImg(ActionEvent event){ 3 FileChooser fileChooser = new FileChooser(); 4 fileChooser.setTitle("选择你要查看的文件"); 5 File file = fileChooser.showOpenDialog(null); 6 if (file != null) { 7 InputStream in = null; 8 byte[] data = null; 9 // 读取图片字节数组 10 try { 11 in = new FileInputStream(file); 12 data = new byte[in.available()]; 13 in.read(data); 14 in.close(); 15 } catch (IOException e) { 16 e.printStackTrace(); 17 } 18 19 try { 20 /*发送消息,告诉别人你发了图片*/ 21 String str = tf_name.getText()+"说:我给你发了张图片"; 22 DatagramPacket p1 = new DatagramPacket(str.getBytes(), str.getBytes().length, ia, 6760); 23 socket.send(p1); 24 // 对字节数组Base64编码 25 BASE64Encoder encoder = new BASE64Encoder(); 26 socket2 = new MulticastSocket(6770); 27 DatagramPacket p2 = new DatagramPacket(encoder.encode(data).getBytes(), encoder.encode(data).getBytes().length, ia, 6770); 28 socket2.joinGroup(ia); 29 socket2.send(p2); 30 } catch (IOException e) { 31 e.printStackTrace(); 32 } 33 } 34 }
使用线程Image_recive对base64编码的数据解码成图片的代码如下:
1 class Image_recive extends Thread { 2 public void run() { 3 byte[] buf = new byte[100]; 4 DatagramPacket recv = new DatagramPacket(buf, buf.length); 5 while (true) { 6 BASE64Decoder decoder = new BASE64Decoder(); 7 try { 8 byte[] buf1 = new byte[100]; 9 DatagramPacket recv1 = new DatagramPacket(buf1, buf1.length); 10 FX_UDP.socket2.receive(recv1); 11 String str = new String(recv.getData(), 0, recv.getLength()); 12 // Base64解码 13 byte[] b = decoder.decodeBuffer(str); 14 for (int i = 0; i < b.length; ++i) { 15 if (b[i] < 0) {// 调整异常数据 16 b[i] += 256; 17 } 18 } 19 // 生成png图片 20 Date day = new Date(); 21 SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss"); 22 String name = df.format(day); 23 OutputStream out = new FileOutputStream("D:/(" + name + ").jpg"); 24 out.write(b); 25 out.flush(); 26 out.close(); 27 } catch (Exception e) { 28 } 29 } 30 } 31 }
Stage模拟一切弹窗,牛逼。
1 public void btnPreview(ActionEvent event){ 2 FileChooser fileChooser = new FileChooser(); 3 fileChooser.setTitle("选择你要查看的文件"); 4 File file = fileChooser.showOpenDialog(null); 5 // String path = file.getPath().toString(); 6 // String str = path.replaceAll("\\\\","\\\\\\\\"); 7 // System.out.print(str); 8 if(file!=null){ 9 Stage stage = new Stage(); 10 BorderPane root = new BorderPane(); 11 String path = file.getPath().toString(); 12 String str = path.replaceAll("\\\\","\\\\\\\\"); 13 Image image = new Image("file:"+str); 14 ImageView iv = new ImageView(); 15 iv.setImage(image); 16 root.setCenter(iv); 17 Scene scene = new Scene(root); 18 stage.setScene(scene); 19 stage.setWidth(400); 20 stage.setHeight(400); 21 stage.show(); 22 } 23 }
1 package 测试; 2 3 import java.io.File; 4 import java.io.FileInputStream; 5 import java.io.FileOutputStream; 6 import java.io.IOException; 7 import java.io.InputStream; 8 import java.io.OutputStream; 9 import java.net.DatagramPacket; 10 import java.net.InetAddress; 11 import java.net.MulticastSocket; 12 import java.text.SimpleDateFormat; 13 import java.util.Date; 14 import java.util.Optional; 15 16 import javafx.application.Application; 17 import javafx.event.ActionEvent; 18 import javafx.scene.Scene; 19 import javafx.scene.control.Alert; 20 import javafx.scene.control.Button; 21 import javafx.scene.control.ButtonType; 22 import javafx.scene.control.Label; 23 import javafx.scene.control.ScrollPane; 24 import javafx.scene.control.TextArea; 25 import javafx.scene.control.TextField; 26 import javafx.scene.control.TitledPane; 27 import javafx.scene.image.Image; 28 import javafx.scene.image.ImageView; 29 import javafx.scene.layout.AnchorPane; 30 import javafx.scene.layout.BorderPane; 31 import javafx.scene.layout.VBox; 32 import javafx.scene.text.Font; 33 import javafx.stage.FileChooser; 34 import javafx.stage.Stage; 35 import sun.misc.BASE64Decoder; 36 import sun.misc.BASE64Encoder; 37 38 public class FX_UDP extends Application { 39 static InetAddress ia; 40 static MulticastSocket socket,socket2; 41 static TextArea ta_1, ta_2; 42 static TextField tf_name; 43 public static void main(String[] args) { 44 try { 45 ia = InetAddress.getByName("228.9.6.7"); 46 socket = new MulticastSocket(6760); 47 socket.joinGroup(ia); 48 new Private_recive().start();//启动接收信息的线程 49 new Image_recive().start();//启动接收图片的线程 50 } catch (IOException e1) { 51 System.out.println("组播地址绑定失败"); 52 } 53 Application.launch(); 54 } 55 56 @Override 57 public void start(Stage s) throws Exception { 58 Label lb_net = new Label("网名:"); 59 lb_net.setFont(Font.font(17));//设置字体大小 60 tf_name = new TextField("JDR"); 61 62 /* 消息记录 */ 63 ta_1 = new TextArea(); 64 ta_1.setPrefSize(400, 200); 65 ScrollPane pane_info = new ScrollPane(ta_1); 66 TitledPane pane_01 = new TitledPane("消息记录", pane_info); 67 /* 发送窗口 */ 68 ta_2 = new TextArea(); 69 ta_2.setPrefSize(400, 100); 70 ScrollPane pane_send = new ScrollPane(ta_2); 71 TitledPane pane_02 = new TitledPane("发送窗口", pane_send); 72 /* 发送和按钮事件 */ 73 Button btn_send = new Button("发送"); 74 btn_send.setOnAction(this::btnSend); 75 /* 关闭和按钮事件 */ 76 Button btn_close = new Button("关闭"); 77 btn_close.setOnAction(this::btnClose); 78 /*发送图片和按钮事件*/ 79 Button btn_img = new Button("选择图片"); 80 btn_img.setOnAction(this::btnImg); 81 Button btn_preview = new Button("预览图片"); 82 btn_preview.setOnAction(this::btnPreview); 83 /* 按钮大小 */ 84 btn_send.setPrefSize(70, 30); 85 btn_close.setPrefSize(70, 30); 86 /* 按钮的位置 */ 87 AnchorPane.setTopAnchor(btn_close, 350.0); 88 AnchorPane.setLeftAnchor(btn_close, 0.0); 89 AnchorPane.setTopAnchor(btn_send, 350.0); 90 AnchorPane.setLeftAnchor(btn_send, 330.0); 91 AnchorPane.setTopAnchor(btn_img, 224.0); 92 AnchorPane.setLeftAnchor(btn_img, 100.0); 93 AnchorPane.setTopAnchor(btn_preview, 224.0); 94 AnchorPane.setLeftAnchor(btn_preview, 160.0); 95 96 AnchorPane.setTopAnchor(lb_net, 20.0); 97 AnchorPane.setLeftAnchor(lb_net, 420.0); 98 AnchorPane.setTopAnchor(tf_name, 20.0); 99 AnchorPane.setLeftAnchor(tf_name, 470.0); 100 101 VBox vb = new VBox(pane_01, pane_02); 102 103 AnchorPane apane = new AnchorPane(vb, btn_send, btn_close,btn_img,btn_preview,lb_net,tf_name); 104 apane.setStyle("-fx-background-color:#FFE4C4");//设置背景色 105 Scene scene = new Scene(apane); 106 107 s.setOnCloseRequest(event -> { 108 Alert alert = new Alert(Alert.AlertType.CONFIRMATION); 109 alert.setTitle("退出"); 110 alert.setHeaderText("你是否要退出?"); 111 Optional<ButtonType> result = alert.showAndWait(); 112 if (result.get() == ButtonType.OK) { 113 try { 114 socket.leaveGroup(ia); 115 System.exit(0); 116 } catch (IOException e) { 117 e.printStackTrace(); 118 } 119 } else { 120 event.consume(); 121 } 122 }); 123 s.setTitle("JDR的午夜群聊"); 124 s.setScene(scene); 125 s.setHeight(450); 126 s.setWidth(650); 127 s.show(); 128 } 129 130 /* 发送按钮事件 */ 131 public void btnSend(ActionEvent enent) { 132 try { 133 String msg = ta_2.getText(); 134 DatagramPacket p = new DatagramPacket(msg.getBytes(), msg.getBytes().length, ia, 6770); 135 socket.send(p); 136 } catch (IOException e) { 137 // TODO 自动生成的 catch 块 138 e.printStackTrace(); 139 } 140 } 141 /*关闭按钮事件*/ 142 public void btnClose(ActionEvent event) { 143 Alert alert = new Alert(Alert.AlertType.CONFIRMATION); 144 alert.setTitle("退出"); 145 alert.setHeaderText("你是否要退出"); 146 Optional<ButtonType> result = alert.showAndWait(); 147 if (result.get() == ButtonType.OK) { 148 System.exit(0); 149 } else { 150 event.consume(); 151 } 152 } 153 /*发送图片按钮事件*/ 154 public void btnImg(ActionEvent event){ 155 FileChooser fileChooser = new FileChooser(); 156 fileChooser.setTitle("选择你要查看的文件"); 157 File file = fileChooser.showOpenDialog(null); 158 if (file != null) { 159 InputStream in = null; 160 byte[] data = null; 161 // 读取图片字节数组 162 try { 163 in = new FileInputStream(file); 164 data = new byte[in.available()]; 165 in.read(data); 166 in.close(); 167 } catch (IOException e) { 168 e.printStackTrace(); 169 } 170 171 try { 172 /*发送消息,告诉别人你发了图片*/ 173 String str = tf_name.getText()+"说:我给你发了张图片"; 174 DatagramPacket p1 = new DatagramPacket(str.getBytes(), str.getBytes().length, ia, 6760); 175 socket.send(p1); 176 // 对字节数组Base64编码 177 BASE64Encoder encoder = new BASE64Encoder(); 178 socket2 = new MulticastSocket(6770); 179 DatagramPacket p2 = new DatagramPacket(encoder.encode(data).getBytes(), encoder.encode(data).getBytes().length, ia, 6770); 180 socket2.joinGroup(ia); 181 socket2.send(p2); 182 } catch (IOException e) { 183 e.printStackTrace(); 184 } 185 } 186 } 187 public void btnPreview(ActionEvent event){ 188 FileChooser fileChooser = new FileChooser(); 189 fileChooser.setTitle("选择你要查看的文件"); 190 File file = fileChooser.showOpenDialog(null); 191 // String path = file.getPath().toString(); 192 // String str = path.replaceAll("\\\\","\\\\\\\\"); 193 // System.out.print(str); 194 if(file!=null){ 195 Stage stage = new Stage(); 196 BorderPane root = new BorderPane(); 197 String path = file.getPath().toString(); 198 String str = path.replaceAll("\\\\","\\\\\\\\"); 199 Image image = new Image("file:"+str); 200 ImageView iv = new ImageView(); 201 iv.setImage(image); 202 root.setCenter(iv); 203 Scene scene = new Scene(root); 204 stage.setScene(scene); 205 stage.setWidth(400); 206 stage.setHeight(400); 207 stage.show(); 208 } 209 } 210 } 211 class Image_recive extends Thread { 212 public void run() { 213 byte[] buf = new byte[100]; 214 DatagramPacket recv = new DatagramPacket(buf, buf.length); 215 while (true) { 216 BASE64Decoder decoder = new BASE64Decoder(); 217 try { 218 byte[] buf1 = new byte[100]; 219 DatagramPacket recv1 = new DatagramPacket(buf1, buf1.length); 220 FX_UDP.socket2.receive(recv1); 221 String str = new String(recv.getData(), 0, recv.getLength()); 222 // Base64解码 223 byte[] b = decoder.decodeBuffer(str); 224 for (int i = 0; i < b.length; ++i) { 225 if (b[i] < 0) {// 调整异常数据 226 b[i] += 256; 227 } 228 } 229 // 生成png图片 230 Date day = new Date(); 231 SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss"); 232 String name = df.format(day); 233 OutputStream out = new FileOutputStream("D:/(" + name + ").jpg"); 234 out.write(b); 235 out.flush(); 236 out.close(); 237 } catch (Exception e) { 238 } 239 } 240 } 241 } 242 243 244 class Private_recive extends Thread { 245 public void run() { 246 247 byte[] buf = new byte[100]; 248 DatagramPacket recv = new DatagramPacket(buf, buf.length); 249 Date day = new Date(); 250 SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 251 try { 252 while (true) { 253 FX_UDP.socket.receive(recv); 254 String str = new String(recv.getData(), 0, recv.getLength()); 255 FX_UDP.ta_1.appendText(df.format(day) + "\n"); 256 FX_UDP.ta_1.appendText(str + "\n"); 257 } 258 } catch (IOException e1) { 259 System.out.println("接受失败"); 260 } 261 } 262 }
emmm,你运行就知道了,不能运行,或者出错了就问我吧。
原文:https://www.cnblogs.com/jdr-gbl/p/12037742.html