我正在尝试将基本的Java概念验证放在一起,以便有一台服务器(很可能只是一台Windows或Linux笔记本电脑)可以将消息发送到同一台WIFI连接的Android设备上子网(最初20-30,但未来可能是一个数字 - 2或300? - 不确定,但我需要考虑这种可能性)。该应用程序将向所有设备发送消息(最初相同的消息 - 但我可能允许在轨道的某个地方发生特殊情况)。然后,每个设备都可以回复,我将要检查哪些设备已回复并存储回复。
我尝试了一些使用UDP的测试代码(在nakov.com的教程中提供了一些帮助),但它非常不可靠,并且在尝试接收数据包时手机经常被锁定 - 虽然它有时候工作得很好。我的Android设备的客户端代码如下所示(请注意,此代码只是发送消息请求,然后接收并显示它 - 我没有按照我想要的方式编写它,因为它没有'似乎足够可靠,无论如何都可以使用。)
所以,我认为我可能需要使用TCP来提高可靠性(尽管我愿意接受建议)。 2-300个单独的TCP并发连接是否可以?并且很可能所有的回复都会立即进入服务器(或者在10-15秒的时间内),这会以一种它无法处理的方式泛滥吗?只有20-30台设备可能没问题吗?
我知道这是一个外面的问题,但我希望有人比我更了解TCP,可以提供一些启示并给我一些指示。
干杯
史蒂夫
UDP客户端应用程序:
package nz.co.et.quoteclient;
import java.io.IOException;
import java.net.DatagramSocket;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import android.app.Activity;
import android.content.Context;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class QuoteClient extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button button = (Button) findViewById(R.id.Button01);
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
if (wifiManager.isWifiEnabled()) {
TextView errorText = (TextView) findViewById(R.id.TextView01);
int serverPort = 4445;
InetAddress address = null;
try {
address = InetAddress.getByName("192.168.1.4");
} catch (UnknownHostException e) {
errorText.setText("Failed at setting server IP Address");
e.printStackTrace();
}
byte[] buf = new byte[256];
DatagramPacket packet = new DatagramPacket(buf, buf.length, address, serverPort);
DatagramSocket socket = null;
try {
socket = new DatagramSocket();
} catch (SocketException e) {
errorText.setText("Failed at creating socket");
e.printStackTrace();
}
try {
socket.send(packet);
} catch (IOException e) {
errorText.setText("Failed at sending request packet");
e.printStackTrace();
}
// get response
packet = new DatagramPacket(buf, buf.length);
try {
socket.receive(packet);
} catch (IOException e) {
errorText.setText("Failed at receiving quote packet from server");
e.printStackTrace();
}
// display response
String message = new String(packet.getData());
String data = "";
for (int i = 0; i < message.length(); i++) {
int tmp = (int) message.charAt(i);
data = (tmp <= 0 || tmp >= 256) ? data += "" : data + message.charAt(i);
}
Toast.makeText(getApplicationContext(), data, Toast.LENGTH_LONG).show();
// errorText.setText(data);
}
else {
Toast.makeText(getApplicationContext(), "WIFI not enabled", Toast.LENGTH_LONG).show();
}
}
});
}
}
答案 0 :(得分:3)
TCP肯定比UDP更可靠,因为UDP不保证数据包传输(这可能是你的应用程序挂在接收上的原因)。
2-300个连接应该是可管理的,但它取决于你的硬件功能和正在处理/来回发送的数据量。
您还必须围绕以下事项做出一些决定:
你用什么语言编写服务器(java?)?
您是否保持从客户端到服务器的持久连接,或每次都重新创建它?
谁负责建立连接(客户端或服务器)?
服务器如何识别哪个设备已收到该消息,是否与IP地址绑定,或者是否正在进行某种握手以识别客户端。
如果客户端已连接,您是否需要发送以前错过的所有信息?
这些信息是否需要同时传递给所有客户,还是可以错开?
如果客户端应用程序失去连接,它是否会重试等,您的客户端应用程序如何运作?
列表继续......
答案 1 :(得分:2)
Depending upon how your program your server,您应该能够处理几千个并发TCP会话。
如果您选择线程,则可能无法扩展到超过100个客户端;每个线程带来足够的每线程存储和调度开销,我真的不想指望超过50个客户端。
新的Java NIO框架提供了一些可用于扩展到数百或数千个并发连接的功能。如果框架在引擎盖下使用select(2)
,它应该能够执行多达1000个并发连接,但如果它使用epoll(2)
或kqueue
或类似的构造,则甚至超过1000个同时联系应该是可行的。
你做什么这些会话可能会规定少得多的同时连接:流媒体视频将比发送一个礼貌的“欢迎来到我们的网络”页面更加密集。