Java + Raspberry Pi + ServerSocket
Java + Raspberry Pi + ServerSocket
你好 Whosebug 社区,
我有一个启动 java.net.ServerSocket on a Raspberry Pi Zero and connect to it with a java.net.Socket 的具体问题。 RPi 配置为无线接入点,因此我可以通过 WLAN 与多个 Laptop/Tablets 连接。目的是启动一个服务器-客户端游戏,以 RPi 作为服务器(不需要单独的网络和设备上的服务器 运行)和一些设备作为客户端(可以连接到 RPi) .
我尝试了以下四种情况,都不止一次地证明它们总是显示相同的结果:
我用平板电脑通过 WLAN 连接到树莓派。然后我在那台平板电脑上启动了 ServerSocket。之后,我在该平板电脑上启动了一个套接字并将其连接到 ServerSocket。连接正常,数据双向传输。
我用平板电脑通过 WLAN 连接到树莓派。然后我在那台平板电脑上启动了 ServerSocket。之后,我在 RPi 上启动了一个 Socket ,并将它连接到我平板电脑上的 ServerSocket 运行。连接正常,数据双向传输。
我用平板电脑通过 WLAN 连接到树莓派。然后我在 RPi 上启动了 ServerSocket 。之后,我在我的平板电脑上启动了一个 Socket,并将它连接到我的 RPi 上的 ServerSocket 运行。第一个奇怪的是ServerSocket的IP是0.0.0.0,第二个是客户端连接树莓派失败导致无法传输数据
我用平板电脑通过 WLAN 连接到树莓派。然后我在 RPi 上启动了 ServerSocket 并将其绑定到指定的 IP 地址。之后,我在我的平板电脑上启动了一个 Socket,并将它连接到我的 RPi 上的 ServerSocket 运行。 ServerSocket 无法绑定到给定的 IP 地址,因此 Socket 无法连接到服务器,因此没有数据传输。
为什么没有IP绑定到ServerSocket(0.0.0.0除外)?为什么我无法连接到 IP 地址 0.0.0.0?如何使用 Java 在 RPi 上获取 ServerSocket 运行?
以下是我在所有三种情况下使用的 java 源代码:
服务器:
import java.net.ServerSocket;
import java.net.InetAddress;
import java.net.Socket;
import java.net.InetSocketAddress;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class Server {
private ServerSocket ss;
public static void main(String[] args) {
new Server(); // call the constructor
}
public Server() {
try {
ss = new ServerSocket(4444); // create the ServerSocket
new Thread(new Runnable() { // create new Thread for listening to new clients
public void run() {
startAccept(); // run the accept-clients method
}
}).start(); // don't forget to start the thread
System.out.println(InetAddress.getLocalHost().getHostAddress()); // print the IP-Address
System.out.println("4444"); // print the Port
} catch (Exception e) {
e.printStackTrace(); // show exceptions
}
}
public void startAccept() {
while (true) { // listen to new clients
try {
Socket so = ss.accept(); // accept the clients and create reader/writer
BufferedReader bure = new BufferedReader(new InputStreamReader(so.getInputStream()));
BufferedWriter buwr = new BufferedWriter(new OutputStreamWriter(so.getOutputStream()));
new Thread(new Runnable() { // start new thread for reading from the client
public void run() {
readSocket(bure, buwr); // run the read/write method of the client
}
}).start(); // don't forget to start the thread
} catch (Exception e) {
e.printStackTrace(); // show exceptions
}
}
}
public void readSocket(BufferedReader bure, BufferedWriter buwr) {
while (true) { // listen to all messages sent by the client
try {
String l1 = bure.readLine(); // read first line
System.out.println("Rec1: <"+l1+">"); // show it
String l2 = bure.readLine(); // read second line
System.out.println("Rec2: <"+l2+">"); // show it
buwr.write(l1+" + "+l2+" = "+(Integer.parseInt(l1)+Integer.parseInt(l2))+"\n");
buwr.flush(); // convert both lines to integers and send the sum of them
} catch (Exception e) {
e.printStackTrace(); // show exceptions
}
}
}
}
客户:
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class Client {
public static void main(String[] args) { // start the program
try {
Socket so = new Socket(); // create an unbound socket
so.connect(new InetSocketAddress("0.0.0.0", 4444), 10000);
// bind socket to the IP-address printed by the Server and create reader/writer
BufferedReader bure = new BufferedReader(new InputStreamReader(so.getInputStream()));
BufferedWriter buwr = new BufferedWriter(new OutputStreamWriter(so.getOutputStream()));
buwr.write("7\n4\n"); // send 7 and 4, both followed by a new line
buwr.flush();
System.out.println("Sent: <7\n4\n>"); // show the user what has been sent
System.out.println("Message from Server: "+bure.readLine()); // sum sent by the server
so.close(); // close socket
} catch (Exception e) {
e.printStackTrace(); // show exception
}
}
}
非常感谢您对此主题的任何帮助。
最后我自己找到了解决办法。
核心问题是将 RPi 设置为具有 this tutorial (without installing a brigde with bridge-utils). It is not possible to access the RPI without a defined static IP address, therefore it is not possible to bind a ServerSocket 到 任何 IP 地址的 WAP。
将静态 IP 地址添加到 RPi WAP 的工作方式如下:
用
编辑文件/etc/network/interfaces
sudo nano /etc/network/interfaces
并将以下行写入文件末尾。
auto wlan0
iface wlan0 inet static
address 192.168.5.1 #Use own IP address here
netmask 255.255.255.0
注意:该文件末尾需要有一个空行。不需要静态 IP 地址在 /etc/dnsmasq.conf
中定义的范围内,但只有在子网掩码适合时才有效(在我的例子中是 192.168.5.xxx)。
下一个问题是我不知道ServerSocket绑定到哪个IP。我通过调用
得到了奇怪的输出(见评论)
System.out.println(InetAddress.getLocalHost().getHostAddress());
System.out.println(ss.getInetAddress().getHostAddress());
和 ss.isBound()
的查询总是返回 true。这个问题的解决方案是将ServerSocket绑定到一个特定的IP地址,这个IP地址与上面在RPi上的interfaces
文件中定义的相同。而不是调用
ss = new ServerSocket(4444);
我用过
ss = new ServerSocket();
ss.bind(new InetSocketAddress("192.168.5.1", 4444));
所以 ServerSocket 开始绑定到我定义的静态 IP 地址。
现在我可以向服务器发送消息,消息在那里被解析,结果被发送回客户端。
你好 Whosebug 社区,
我有一个启动 java.net.ServerSocket on a Raspberry Pi Zero and connect to it with a java.net.Socket 的具体问题。 RPi 配置为无线接入点,因此我可以通过 WLAN 与多个 Laptop/Tablets 连接。目的是启动一个服务器-客户端游戏,以 RPi 作为服务器(不需要单独的网络和设备上的服务器 运行)和一些设备作为客户端(可以连接到 RPi) .
我尝试了以下四种情况,都不止一次地证明它们总是显示相同的结果:
我用平板电脑通过 WLAN 连接到树莓派。然后我在那台平板电脑上启动了 ServerSocket。之后,我在该平板电脑上启动了一个套接字并将其连接到 ServerSocket。连接正常,数据双向传输。
我用平板电脑通过 WLAN 连接到树莓派。然后我在那台平板电脑上启动了 ServerSocket。之后,我在 RPi 上启动了一个 Socket ,并将它连接到我平板电脑上的 ServerSocket 运行。连接正常,数据双向传输。
我用平板电脑通过 WLAN 连接到树莓派。然后我在 RPi 上启动了 ServerSocket 。之后,我在我的平板电脑上启动了一个 Socket,并将它连接到我的 RPi 上的 ServerSocket 运行。第一个奇怪的是ServerSocket的IP是0.0.0.0,第二个是客户端连接树莓派失败导致无法传输数据
我用平板电脑通过 WLAN 连接到树莓派。然后我在 RPi 上启动了 ServerSocket 并将其绑定到指定的 IP 地址。之后,我在我的平板电脑上启动了一个 Socket,并将它连接到我的 RPi 上的 ServerSocket 运行。 ServerSocket 无法绑定到给定的 IP 地址,因此 Socket 无法连接到服务器,因此没有数据传输。
为什么没有IP绑定到ServerSocket(0.0.0.0除外)?为什么我无法连接到 IP 地址 0.0.0.0?如何使用 Java 在 RPi 上获取 ServerSocket 运行?
以下是我在所有三种情况下使用的 java 源代码:
服务器:
import java.net.ServerSocket;
import java.net.InetAddress;
import java.net.Socket;
import java.net.InetSocketAddress;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class Server {
private ServerSocket ss;
public static void main(String[] args) {
new Server(); // call the constructor
}
public Server() {
try {
ss = new ServerSocket(4444); // create the ServerSocket
new Thread(new Runnable() { // create new Thread for listening to new clients
public void run() {
startAccept(); // run the accept-clients method
}
}).start(); // don't forget to start the thread
System.out.println(InetAddress.getLocalHost().getHostAddress()); // print the IP-Address
System.out.println("4444"); // print the Port
} catch (Exception e) {
e.printStackTrace(); // show exceptions
}
}
public void startAccept() {
while (true) { // listen to new clients
try {
Socket so = ss.accept(); // accept the clients and create reader/writer
BufferedReader bure = new BufferedReader(new InputStreamReader(so.getInputStream()));
BufferedWriter buwr = new BufferedWriter(new OutputStreamWriter(so.getOutputStream()));
new Thread(new Runnable() { // start new thread for reading from the client
public void run() {
readSocket(bure, buwr); // run the read/write method of the client
}
}).start(); // don't forget to start the thread
} catch (Exception e) {
e.printStackTrace(); // show exceptions
}
}
}
public void readSocket(BufferedReader bure, BufferedWriter buwr) {
while (true) { // listen to all messages sent by the client
try {
String l1 = bure.readLine(); // read first line
System.out.println("Rec1: <"+l1+">"); // show it
String l2 = bure.readLine(); // read second line
System.out.println("Rec2: <"+l2+">"); // show it
buwr.write(l1+" + "+l2+" = "+(Integer.parseInt(l1)+Integer.parseInt(l2))+"\n");
buwr.flush(); // convert both lines to integers and send the sum of them
} catch (Exception e) {
e.printStackTrace(); // show exceptions
}
}
}
}
客户:
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class Client {
public static void main(String[] args) { // start the program
try {
Socket so = new Socket(); // create an unbound socket
so.connect(new InetSocketAddress("0.0.0.0", 4444), 10000);
// bind socket to the IP-address printed by the Server and create reader/writer
BufferedReader bure = new BufferedReader(new InputStreamReader(so.getInputStream()));
BufferedWriter buwr = new BufferedWriter(new OutputStreamWriter(so.getOutputStream()));
buwr.write("7\n4\n"); // send 7 and 4, both followed by a new line
buwr.flush();
System.out.println("Sent: <7\n4\n>"); // show the user what has been sent
System.out.println("Message from Server: "+bure.readLine()); // sum sent by the server
so.close(); // close socket
} catch (Exception e) {
e.printStackTrace(); // show exception
}
}
}
非常感谢您对此主题的任何帮助。
最后我自己找到了解决办法。
核心问题是将 RPi 设置为具有 this tutorial (without installing a brigde with bridge-utils). It is not possible to access the RPI without a defined static IP address, therefore it is not possible to bind a ServerSocket 到 任何 IP 地址的 WAP。
将静态 IP 地址添加到 RPi WAP 的工作方式如下:
用
编辑文件/etc/network/interfacessudo nano /etc/network/interfaces
并将以下行写入文件末尾。
auto wlan0
iface wlan0 inet static
address 192.168.5.1 #Use own IP address here
netmask 255.255.255.0
注意:该文件末尾需要有一个空行。不需要静态 IP 地址在 /etc/dnsmasq.conf
中定义的范围内,但只有在子网掩码适合时才有效(在我的例子中是 192.168.5.xxx)。
下一个问题是我不知道ServerSocket绑定到哪个IP。我通过调用
得到了奇怪的输出(见评论)System.out.println(InetAddress.getLocalHost().getHostAddress());
System.out.println(ss.getInetAddress().getHostAddress());
和 ss.isBound()
的查询总是返回 true。这个问题的解决方案是将ServerSocket绑定到一个特定的IP地址,这个IP地址与上面在RPi上的interfaces
文件中定义的相同。而不是调用
ss = new ServerSocket(4444);
我用过
ss = new ServerSocket();
ss.bind(new InetSocketAddress("192.168.5.1", 4444));
所以 ServerSocket 开始绑定到我定义的静态 IP 地址。 现在我可以向服务器发送消息,消息在那里被解析,结果被发送回客户端。