0%

java Socket初探—服务器与局域网

自己很久以来一直想做个局域网内传输文件的程序,一直没有动手。这次学习了一下要用到的局域网内的socket通信,在此做个记录。

局域网内的socket通信

并无特别之处,只是需要使用内网IP来建立连接。服务端开启一个ServerSocket,监听特定的端口,获取输出流向客户端写入数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
try {
ServerSocket serverSocket = new ServerSocket(9998);
// 也可以绑定监听的IP,应为内网IP
//ServerSocket serverSocket = new ServerSocket(9998, 50, InetAddress.getByName("xx.xx.xx.xx")); // xx.xx.xx.xx 为本机的内网IP
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)); // xx.xx.xx.xx 为服务端的内网IP
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); // 监听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();
}