我在 Android 上使用 Sockets 时遇到问题。我是这个话题的新手,所以我尝试实现一个简单的聊天,Android 手机到另一个 Android 手机作为培训。
我可以使用我的代码创建一个 ServerSocket 并使用来自同一设备的另一个 Socket 连接到它(一个设备上只有一个客户端的“回声”示例工作正常)我已经完成了在同一个 wifi 上使用两个 IP 地址(192.168 ...),但任何尝试使用 3G 连接使用互联网 IP 地址连接远程客户端的尝试都失败了
java.net.SocketException: recvfrom failed: ETIMEDOUT (Connection timed out)
我所做的是,创建 ServerSocket (ServerConnect.java) :
private ServerSocket _mainServer = null;
private void initServer() {
try {
//port I use here is arbitrary: 8081
_mainServer = new ServerSocket(CONNECT_SOCKET_PORT);
} catch (IOException e) {
Log.w("ServerSocket", e.toString());
e.printStackTrace();
}
}
在同一个类中,在一个单独的线程中,我这样做是为了等待客户端连接:
while (running) {
GuestConnect ssc = new GuestConnect(_mainServer.accept());
ssc.setListener(this);
ssc.startConnection();
_clientSockets.add(ssc);
performGuestAdded("bra!");
}
它使服务器等待多个客户端连接,因此它可以在“聊天室”中容纳两个以上的人。
通信服务器端由本地客户端回调组成,并向我的所有客人发送消息(我仍在处理这部分,它还没有真正完成,但我认为它与我的问题无关):
public void onMessageReceived(TBTGuestConnect sender, String message) {
for(TBTGuestConnect guestConnect : _clientSockets)
if(guestConnect != sender)
guestConnect.sendMessage(message);
}
客户端存储为“GuestConnect”对象,这是我设置它们的方式(GuestConnect.java):
public class GuestConnect {
private StringBuilder _currentMessage;
private BufferedReader _is;
private PrintStream _os;
private Socket _clientSocket = null;
private String _hostname;
private boolean _running = false;
public GuestConnect(String hostname) {
_hostname = hostname;
_currentMessage = new StringBuilder();
}
clientSocket 初始化(仍然是 GuestConnect.java):
private void initSocket() {
if(_clientSocket==null)
{
// Try to open a server socket on given port
// Here is the fail when I called it from another device
try {
_clientSocket = new Socket(_hostname, ServerConnect.CONNECT_SOCKET_PORT);
} catch (IOException e) {
Log.w("GuestSocket", e.toString());
}
}
// Create a socket object from the ServerSocket to listen and accept
// connections.
// Open input and output streams
try {
_is = new BufferedReader(new InputStreamReader(_clientSocket.getInputStream()));
_os = new PrintStream(_clientSocket.getOutputStream());
} catch (IOException e) {
Log.w("GuestSocket", e.toString());
}
}
同样,在同一个班级中,有交流部分:
initSocket();
_running = true;
performConnectionStarted();
try {
while (_running) {
String received = _is.readLine();
_currentMessage.append(received);
if (received.contains(ServerConnect.CONNECT_SOCKET_MESSAGE_END)) {
String finalMsg = _currentMessage.toString().substring(0, _currentMessage.lastIndexOf(ServerConnect.CONNECT_SOCKET_MESSAGE_END));
performMessageReceived(finalMsg);
_currentMessage.setLength(0);
}
}
} catch (IOException e) {
Log.w("GuestSocket", e.toString());
performError(e);
} finally {
try {
_os.close();
_is.close();
_clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
performError(e);
}
_clientSocket = null;
}
然后我可以通过这种方法发送消息:
public void sendMessage(String toSend) {
if (_running)
_os.println(toSend+ServerConnect.CONNECT_SOCKET_MESSAGE_END);
else
throw new IllegalStateException("Send message : Connection isn't started !");
}
所以问题是,我应该怎么做才能使用全球互联网 IP 地址使其工作?
更一般地说,相同的wifi本地IP地址和互联网IP地址之间的技术区别是什么?