我正在尝试使服务器向所有已连接的客户端发送已收到的任何输入。我正在使用一个服务,在创建它时启动一个线程。
public void onCreate()
{
Thread fst = new Thread(new ServerThread());
fst.start();
}
这是线程
public void run()
{
try
{
serverSocket = new ServerSocket(SERVERPORT);
while (true)
{
// listen for incoming clients
Socket client = serverSocket.accept();
mclients = new Vector<Socket>();
mclients.add(client);
boolean finished = false;
try
{
for(int i=0; i<mclients.size(); i++) {
DataInputStream in = new DataInputStream(mclients.get(i).getInputStream());
PrintStream out = new PrintStream(mclients.get(i).getOutputStream());
// Print a message:
System.out.println("Client from : " + mclients.get(i).getInetAddress() + " port " + mclients.get(i).getPort());
// now get the input from the socket...
while(!finished)
{
String st = in.readLine();
// Send the same back to client
out.println(st);
// Write it to the screen as well
System.out.println(st);
// If the input was "quit" then exit...
if (st.equals("quit")) { finished = true; System.out.println("Thread exiting..."); }
}
}
handler.post(new Runnable() {@Override public void run() {}});
}
catch (final Exception e) {handler.post(new Runnable() {@Override public void run() {}});e.printStackTrace();}
}
它仅适用于发送输入的客户端。输入没有回复给所有客户。任何人都可以帮我解决这个问题。我认为我的客户端代码错了,但我无法理解。这是我的客户代码:
public class Client extends Activity implements OnClickListener{
private EditText serverIp;
private static EditText data;
private TextView receivedata, answer1 ,answer2, answer3, answer4;
private Button connectPhones, send;
private String serverIpAddress = "";
private boolean connected = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.client);
serverIp = (EditText) findViewById(R.id.server_ip);
receivedata = (TextView) findViewById(R.id.textView1);
answer1 = (TextView) findViewById(R.id.txtans1);
answer2 = (TextView) findViewById(R.id.txtans2);
answer3 = (TextView) findViewById(R.id.txtans3);
answer4 = (TextView) findViewById(R.id.txtans4);
data = (EditText) findViewById(R.id.data);
connectPhones = (Button) findViewById(R.id.connect_phones);
send = (Button) findViewById(R.id.send);
connectPhones.setOnClickListener(this);
send.setOnClickListener(this);
}
@Override
public void onClick(View v) {
if(v == send)
{
if (!connected)
{
serverIpAddress = serverIp.getText().toString();
if (!serverIpAddress.equals(""))
{
Thread cThread = new Thread(new ClientThread());
cThread.start();
}
}
}
}
public class ClientThread implements Runnable
{
String line;
String[] answers = new String[5];
final Handler handler = new Handler();
final Runnable updateUI = new Runnable() {
public void run() {
receivedata.setText( line );
//answer1.setText( answers[1] );
//answer2.setText( answers[2] );
//answer3.setText( answers[3] );
//answer4.setText( answers[4] );
}
};
public void run()
{
try
{
InetAddress serverAddr = InetAddress.getByName(serverIpAddress);
Log.d("ClientActivity", "C: SENDING...");
Socket socket = new Socket(serverAddr, 5000);
connected = true;
while(connected)
{
try
{
BufferedReader in = new BufferedReader( new InputStreamReader( socket.getInputStream()));
PrintStream out = new PrintStream(socket.getOutputStream());
out.println(data.getText());
line = in.readLine(); // read server
System.out.println("Echo: " + line);
handler.post(updateUI);
in.close(); // Close stream
out.close();
}
catch (Exception e)
{
Log.e("ClientActivity", "S: Error", e);
}
connected = false;
}
Log.d("ClientActivity", "C: Closed.");
} catch (Exception e)
{
Log.e("ClientActivity", "C: Error", e);
}
}
}}
----- ------ EDIT
我应该使用不同的线程来处理客户端,否则会出现问题?那我该怎么办?
答案 0 :(得分:1)
我看到你也在循环中实例化ServerSocket本身。 你不需要为每个连接创建一个新的serversocket,你只需要一个服务器套接字然后循环接受连接并添加连接(已在oncreate()实例化列表中)。见下面的例子。
如果这仍然不起作用,那么我们将不得不看到其余的代码。 而且我想再次强调,这并不总是适用于Android,因为Android也可以杀死你的服务和应用程序以获取资源,每次wifi,3g或手机上的任何东西都会失去连接,你的套接字可能会失败。< / p>
ArrayList<Socket> mCLients;
ServerSocket serverSocket;
public void onCreate()
{
mCLients; = new ArrayList<Socke>();
serverSocket = new ServerSocket(SERVERPORT);
Thread fst = new Thread(new ServerThread());
fst.start();
}
// .....
private Static void send(final String message){
Thread thread = new Thread(){
for(Socket socket: mClients){
// send message to the socket
}
}
thread.start();
}
// ...
public void run(){
while (true)
{
// listen for incoming clients
Socket client = serverSocket.accept();
mclients.add(client);
//Read client input
MyService.send(message);
}
}
请注意,这段代码绝不是最佳方式,我只是简单介绍一下如何处理这个问题。
答案 1 :(得分:0)
通过快速(非常快速)看起来我相信你的问题似乎是在run()中的以下代码
mclients = new Vector();
每次程序运行时都会创建一个新的矢量对象。
我建议将其移出run(),并确保在启动侦听传入连接的线程之前创建了mClients。
但请注意:在Android手机上运行服务器是个坏主意!移动电话具有诸如电池寿命有限,处理,存储器和互联网连接不一致的限制,还有其他方式来处理这种通信。例如考虑消息传递,c2dm,xmpp等。