0

我正在尝试创建一个服务器,它将接收到的任何输入发送回所有连接的客户端。我正在使用一个在创建它时启动一个线程的服务。

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);

                        }
        }        
        }}

-----编辑-----
我应该使用不同的线程来处理客户端还是会出现问题?我该怎么做?

4

2 回答 2

1

我看到您也在循环中实例化 ServerSocket 本身。您不需要为每个连接创建一个新的服务器套接字,您只需要一个服务器套接字然后循环接受连接并将连接添加到(已经在 oncreate() 中实例化)列表。请参见下面的示例。

如果这仍然不起作用,那么我们还必须查看其余代码。我想再次强调,这并不总是适用于 android,因为 android 也可以杀死你的服务和应用程序以获取资源,并且每次 wifi、3g 或手机上的任何东西失去连接时,你的套接字都可能失败。

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);
                }  

 }

请注意,此代码绝不是最好的方法,我只是给您一个快速示例,说明您应该如何处理这个问题。

于 2012-05-14T21:25:45.007 回答
0

通过快速(非常快速)查看,我相信您的问题似乎是 run() 中的以下代码

mclients = 新向量();

每次程序运行时,您都在创建一个新的矢量对象。

我建议将其移出 run(),并确保在启动侦听传入连接的线程之前创建您的 mClients。

但是请注意:在安卓手机上运行服务器是个坏主意!手机有一些限制,例如有限的电池寿命、处理能力、内存和不一致的互联网连接,还有其他方法可以处理这种通信。例如考虑消息传递、c2dm、xmpp 等。

于 2012-05-14T15:41:12.190 回答