Socket.connect(InetSocketAddress, timeout) 不起作用,而 new Socket(InetAddress, port) 起作用
我偶然发现了一些非常奇特的东西。当我尝试在对等应用程序中连接到 LAN 服务器时,socket.connect
似乎不起作用,而 new Socket
却起作用。 提供的 InetAddress 是链接本地 IPV6,但这不应该(?)成为此错误的一个因素。 这是有效的代码:
@Override
public void createUserSocket() throws IOException, InvalidPortValueException {
if (!portIsValid()) throw new InvalidPortValueException();
shutdown();
Log.d(TAG + ".createUserSocket", "TRYING TO CONNECT TO " + address.getHostAddress() + " : " + port);
currentUserSocket = new SocketAdapter(address, port);
currentUserSocket.setTimeout(SO_TIMEOUT);
Log.d(TAG + ".createUserSocket", "connected to " + currentUserSocket.log());
}
这是无效的代码:
@Override
public void createUserSocket() throws IOException, InvalidPortValueException {
if (!portIsValid()) throw new InvalidPortValueException();
shutdown();
currentUserSocket = new SocketAdapter();
InetSocketAddress soAddr = new InetSocketAddress(address, port);
Log.e(TAG + ".createUserSocket", "TRYING TO CONNECT TO " + soAddr.getAddress().getHostAddress() + " " + soAddr.getPort() + " with timeout " + SO_TIMEOUT);
currentUserSocket.connect(soAddr, SO_TIMEOUT);
Log.d(TAG + ".createUserSocket", "connected to " + currentUserSocket.log());
}
值得注意的是,SocketAdapter 只是 Socket 类的包装类,并且不执行任何有趣的操作。 SocketAdapter 的相关代码如下。
SO_TIMEOUT 是一个变量,指定超时时间(以毫秒为单位),地址 &两个块的端口保持相同:
private static final int SO_TIMEOUT = 2000;
private final InetAddress address;
private final int port;
第一个示例按预期工作,连接并且一切正常。 第二个例子不起作用,而是永远阻塞。
我得到了地址&连接外部的端口;但是,正如我之前所说,第一个示例有效,而第二个示例则无效,在 .connect
方法中永远阻塞。 我很感激对这种行为的任何见解,因为这是我的应用程序效率的关键部分。先感谢您!
请注意,我测试的两个设备分别是 API 26 和 30。两款都是 A 系列三星手机(不同代)。
SocketAdapter
private Socket socket;
public SocketAdapter() {}
public SocketAdapter(Socket s) {
socket = s;
}
public SocketAdapter(InetAddress address, int port) throws IOException {
socket = StaticSocketFactory.createSocket(address, port);
}
public InetAddress getInetAddress() {
return socket.getInetAddress();
}
public void connect(SocketAddress addr, int soTimeout) throws IOException {
socket.connect(addr, soTimeout);
}
静态SocketFactory
static Socket createSocket(InetAddress addr, int port) throws IOException {
return new Socket(addr, port);
}
I've stumbled upon something very peculiar. When I'm trying to connect to a LAN server in my peer to peer application, it looks like socket.connect
doesn't work, while the new Socket
does.
The InetAddress provided are link-local IPV6s, however that should(?) not be a factor in this bug.
Here's the code that works:
@Override
public void createUserSocket() throws IOException, InvalidPortValueException {
if (!portIsValid()) throw new InvalidPortValueException();
shutdown();
Log.d(TAG + ".createUserSocket", "TRYING TO CONNECT TO " + address.getHostAddress() + " : " + port);
currentUserSocket = new SocketAdapter(address, port);
currentUserSocket.setTimeout(SO_TIMEOUT);
Log.d(TAG + ".createUserSocket", "connected to " + currentUserSocket.log());
}
Here's the code that doesn't:
@Override
public void createUserSocket() throws IOException, InvalidPortValueException {
if (!portIsValid()) throw new InvalidPortValueException();
shutdown();
currentUserSocket = new SocketAdapter();
InetSocketAddress soAddr = new InetSocketAddress(address, port);
Log.e(TAG + ".createUserSocket", "TRYING TO CONNECT TO " + soAddr.getAddress().getHostAddress() + " " + soAddr.getPort() + " with timeout " + SO_TIMEOUT);
currentUserSocket.connect(soAddr, SO_TIMEOUT);
Log.d(TAG + ".createUserSocket", "connected to " + currentUserSocket.log());
}
It's worthwhile to note SocketAdapter is just a wrapper class for the Socket class, and doesn't do any funny stuff. The relevant bits of code for SocketAdapter are below.
SO_TIMEOUT is a variable specifying timeout in millisecond time, and address & port remain the same from the two blocks:
private static final int SO_TIMEOUT = 2000;
private final InetAddress address;
private final int port;
The first example works as expected, connects and everything's OK.
The second example doesn't work, and instead blocks forever.
I get the address & port to connect to externally; however, as I said before, the first example works, while the second example doesn't, blocking forever in the .connect
method.
I'd appreciate any insight for this sort of behaviour, since this is a critical part for the efficiency of my application. Thank you in advance!
Note, that the two devices I'm testing with, are API 26 and 30 respectively. Both are A-Series SAMSUNG phones (from different generations).
SocketAdapter
private Socket socket;
public SocketAdapter() {}
public SocketAdapter(Socket s) {
socket = s;
}
public SocketAdapter(InetAddress address, int port) throws IOException {
socket = StaticSocketFactory.createSocket(address, port);
}
public InetAddress getInetAddress() {
return socket.getInetAddress();
}
public void connect(SocketAddress addr, int soTimeout) throws IOException {
socket.connect(addr, soTimeout);
}
StaticSocketFactory
static Socket createSocket(InetAddress addr, int port) throws IOException {
return new Socket(addr, port);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我不明白你如何尝试创建套接字,但如果你想使用套接字,你必须这样做:
定义一个服务器套接字
ServerSocket serverSocket = new ServerSocket(8080);
然后就可以等待客户端连接了
Socket socket = serverSocket.accept();
我邀请您为连接到您的服务器的每个客户端创建一个线程。并且不要忘记关闭套接字。
I don't understand how you try to create socket but if you want use socket you have to do it this way :
Defind a serversocket
ServerSocket serverSocket = new ServerSocket(8080);
Then you can wait for a client to connect
Socket socket = serverSocket.accept();
I invite you to create a thread for each client that connect to your server. And don't forget to close your socket.