在Android/Java中设置S/C之间的TCP连接
我正在设计一个全对全Android程序,包括5个节点:在Android/Java中设置S/C之间的TCP连接,android,tcp,multicast,Android,Tcp,Multicast,我正在设计一个全对全Android程序,包括5个节点: 每个节点同时充当服务器和客户端 每个节点将连接到其他4个节点 每个节点将侦听并接受其他4个节点的连接 但我的问题是,如果5个节点按:1-2-3-4-5的顺序启动,Node1的tcp连接请求将不会被Node2接受,因为Node2在1之后启动 为了解决这个问题,我尝试使用isConnected(),但它总是返回true,即使只有Node1启动 所以我的问题是如何在3个Android节点之间建立一个全对全TCP连接 附件是我的代码: privat
isConnected()
,但它总是返回true
,即使只有Node1启动
所以我的问题是如何在3个Android节点之间建立一个全对全TCP连接
附件是我的代码:
private class ClientTask extends Thread {
Socket[] s1 = new Socket[5];
@Override
public void run() {
int flag=1;
for (int i = 0; i < 5; i++) {
if(flag==0) i--;
try {
System.out.println("Begin making connections!");
//s1[i] = new Socket(InetAddress.getByAddress(new byte[]{10, 0, 2, 2}),REMOTE_PORT[i]);
s1[i] = new Socket();
s1[i].connect(new InetSocketAddress("10.0.2.2", REMOTE_PORT[i]),1000);
flag=1;
} catch (UnknownHostException e) {
System.out.println("ClientTask UnknownHostException");
flag=0;
} catch (IOException e) {
//Error happens when set_redir.py is not run
System.out.println("ClientTask socket IOException");
flag=0;
}
}
}
}
private类ClientTask扩展线程{
套接字[]s1=新套接字[5];
@凌驾
公开募捐{
int标志=1;
对于(int i=0;i<5;i++){
如果(标志==0)i--;
试一试{
System.out.println(“开始建立连接!”);
//s1[i]=新套接字(InetAddress.getByAddress(新字节[]{10,0,2,2}),远程_端口[i]);
s1[i]=新套接字();
s1[i].connect(新的InetSocketAddress(“10.0.2.2”,远程_端口[i]),1000);
flag=1;
}捕获(未知后异常e){
System.out.println(“ClientTaskUnknownHostException”);
flag=0;
}捕获(IOE异常){
//未运行set_redir.py时发生错误
System.out.println(“ClientTask套接字IOException”);
flag=0;
}
}
}
}
以及服务器的代码:
public class ServerTask extends Thread {
ServerSocket serverSocket = null;
public void run() {
System.out.println("Start listening!");
Socket socket = null;
try {
serverSocket = new ServerSocket(10000);
} catch (IOException e) {
System.out.println("Error when creating serversocket!");
}
int flag=1;
for (int i = 0; i < 5; i++) {
if(flag==0) i--;
try {
// waiting for incoming socket
socket = serverSocket.accept();
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
try{
out.writeBytes("You are connected to avd: " + (myPort-11108)/4);
}catch (IOException e){
System.out.println("Error here!");
}
flag=1;
// new thread for the full TCP connection
System.out.println("Receiving new TCP connection from " + socket.getRemoteSocketAddress());
tt[i] = new tcpThread(socket, i);
tt[i].start();
} catch (IOException e) {
System.out.println("ERROR: server socket");
flag=0;
}
}
System.out.println("End listening...");
}
}
public类ServerTask扩展线程{
ServerSocket ServerSocket=null;
公开募捐{
System.out.println(“开始监听!”);
套接字=空;
试一试{
serverSocket=新的serverSocket(10000);
}捕获(IOE异常){
System.out.println(“创建serversocket时出错!”);
}
int标志=1;
对于(int i=0;i<5;i++){
如果(标志==0)i--;
试一试{
//等待传入套接字
socket=serverSocket.accept();
DataOutputStream out=新的DataOutputStream(socket.getOutputStream());
试一试{
out.writeBytes(“您已连接到avd:”+(myPort-11108)/4);
}捕获(IOE异常){
System.out.println(“此处出错!”);
}
flag=1;
//完整TCP连接的新线程
System.out.println(“从“+socket.getRemoteSocketAddress()”接收新的TCP连接);
tt[i]=新的tcpThread(socket,i);
tt[i].start();
}捕获(IOE异常){
System.out.println(“错误:服务器套接字”);
flag=0;
}
}
System.out.println(“结束侦听…”);
}
}
在Stackoverflow和google做了一些研究之后,我找到了检测服务器是否在线或离线的方法。我正在写以下笔记,以防将来有人面临同样的问题:>
无论服务器是否在线,我们都可以使用read()
或readLine()
,而不是使用isConnected()
,只要连接确实是由客户端发出的,这将始终是true
read()
将返回-1
,如果由于连接丢失、服务器关闭等原因未实际设置连接
readLine()
将一直计时,与上述情况相同
因此,我们可以检查返回值是
-1
还是超时readLine()
,以检查TCP连接的状态。什么是“S/C”?短路?@EJP服务器/客户端…为什么不这么说?一切都不是TLA。可能什么都有,到处都是错误。如果read()
返回-1,readLine()
将在相同的情况下返回null
,而不是永远阻塞isConnected()
在连接或接受套接字后永远返回true。它是套接字的属性,而不是连接的属性。如果连接丢失,则说明read()
将返回-1是不正确的。可靠地检测的唯一方法是发送。如果您能区分服务器不活动和响应失败,读取超时可能会有所帮助。@EJP Thx供您评论!我正在做一个项目,面临不少TCP问题。从read()
返回值的文档中,数据的下一个字节,或者-1(如果到达流的结尾)。
。那么为什么我们不能说如果连接丢失,read()将返回-1呢。
?因为它可能会永远阻塞read()
不会发出任何网络协议,因此它只会等待某些事情发生,而在死掉的连接上发生某些事情的唯一方法是尝试向其发送。