自己很久以来一直想做个局域网内传输文件的程序,一直没有动手。这次学习了一下要用到的局域网内的socket通信,在此做个记录。
局域网内的socket通信
并无特别之处,只是需要使用内网IP来建立连接。服务端开启一个ServerSocket,监听特定的端口,获取输出流向客户端写入数据。
1 2 3 4 5 6 7 8 9 10 11 12 13
| try { ServerSocket serverSocket = new ServerSocket(9998); while (true) { Socket s = serverSocket.accept(); PrintWriter pw = new PrintWriter(s.getOutputStream()); pw.println("hello world"); pw.flush(); } } catch (IOException e) { e.printStackTrace(); }
|
客户端向服务端的”内网IP:指定端口“发送连接请求,读写数据,
1 2 3 4 5 6 7 8 9 10 11 12 13
| try { Socket s = new Socket(); s.connect(new InetSocketAddress("xx.xx.xx.xx", 9998)); BufferedInputStream in = new BufferedInputStream(s.getInputStream());
int len = 0; byte[] bytes = new byte[1024]; while ((len = in.read(bytes)) != -1) { System.out.println(new String(bytes, 0, len)); } } catch (IOException e) { e.printStackTrace(); }
|
另外,需要设置防火墙把使用的端口开放才可以成功。
以上的例子是客户端已知服务端内网IP下进行的,而想做的局域网内文件传输的程序如果还需要用户手动输入IP就贻笑大方了。为了可以在不知道服务端IP情况下开始建立连接,我们可以在客户端发送一个UDP广播。
UDP广播
UDP 的主要实现在DatagramSocket类,在服务端监听指定端口,
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| DatagramSocket ds = null; try { ds = new DatagramSocket(9998); byte[] buf = new byte[1024]; DatagramPacket dp = new DatagramPacket(buf, 1024); ds.receive(dp); String data = new String(dp.getData(), 0, dp.getLength()); System.out.println(data); ds.close(); } catch (SocketException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }
|
报文类DatagramPacket对象还存储了发送方的IP地址InetAddress address和端口port,可以使用getAddress()和getPort()得到。
客户端则是发送一个广播,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| DatagramSocket s = null; try { s = new DatagramSocket(); String str = "hello, I'm client"; DatagramPacket dp = new DatagramPacket(str.getBytes(), str.getBytes().length, InetAddress.getByName("255.255.255.255"), 9998);
s.send(dp); } catch (SocketException e) { e.printStackTrace(); } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }
|