Android聊天客户端:套接字连接

时间:2016-03-06 23:41:10

标签: java android sockets

我是Android新手。首先,我用Java编写了一个Chat_Client和Server。它很棒。

然后我尝试将其转换为有效的Android应用程序,我总是收到消息"无法连接到服务器!再试一次!"所以Socket连接尝试显然有问题,但我无法弄清楚它是什么。

背景知识:
- 我连接到我的根服务器,看看chat_server进程。它正在运行!
- 我试图从我的PC上的其他chat_client连接到chat_server。它有效!
- 主机和端口是正确的。检查了几次 - 权限设置<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
- 我可以在我的Nexus 5上运行应用程序 - LogCat或控制台中没有列出错误,它似乎正常运行..

我的chat_client代码:

package de.Voldemord.chatter;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.*;
import java.io.*;
import java.net.*;
import java.util.*;

public class MainActivity extends Activity implements OnClickListener{
    private Button btn;
    private EditText et_send;
    private EditText et_chat;
    private String s_username = "Voldemord", s_host = "www.example.com";         // !Example host!
    private int s_port = 2222;                                                   // !Example port!
    private Socket socket = null;
    private BufferedReader in;
    private PrintWriter out;
    @SuppressWarnings({ "unchecked", "rawtypes" })
    ArrayList<String> users = new ArrayList();
    boolean isConnected = false;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    et_send = (EditText) findViewById(R.id.sendTextView);
    et_chat = (EditText) findViewById(R.id.chatTextView);

    btn = (Button) findViewById(R.id.btn);
    btn.setOnClickListener(this);


    if (isConnected == false){
        try{
            socket = new Socket(InetAddress.getByName(s_host), s_port);
            InputStreamReader streamreader = new InputStreamReader(socket.getInputStream());
            in = new BufferedReader(streamreader);
            out = new PrintWriter(socket.getOutputStream());
            out.println(s_username + ":has connected.:Connect");
            out.flush(); 
            isConnected = true; 
        }catch (Exception ex){
            et_chat.append("Cannot Connect! Try Again. \n"+ socket);
        }

        ListenThread();

    }else if (isConnected == true){
        et_chat.append("You are already connected. \n");
    }

}

protected void onDestroy(){
    super.onDestroy();
    sendDisconnect();
    Disconnect();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();
    if (id == R.id.action_settings) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}

@Override
public void onClick(View v) {   
    String nothing = "";
    if ((et_send.getText()).equals(nothing)) {
        et_send.setText("");
        et_send.requestFocus();
    } else {
        try {
           out.println(s_username + ":" + et_send.getText() + ":" + "Chat");
           out.flush(); // flushes the buffer
        } catch (Exception ex) {
            et_chat.append("Message was not sent. \n");
        }
        et_send.setText("");
        et_send.requestFocus();
    }

    et_send.setText("");
    et_send.requestFocus();
}

public void sendDisconnect(){
    String bye = (s_username + ": :Disconnect");
    try{
        out.println(bye);
        out.flush();
    }catch (Exception e){
        et_chat.append("Could not send Disconnect message.\n");
    }
}

public void Disconnect(){
    try{
        et_chat.append("Disconnected.\n");
        socket.close();
    }catch (Exception e){
        et_chat.append("Failed to disconnect.\n");
    }
    isConnected = false;
}

public void ListenThread(){
    Thread IncomingReader = new Thread(new IncomingReader());
    IncomingReader.start();
}

public void userAdd(String user){
    users.add(user);
}

public void userRemove(String user){
    et_chat.append(user + " is now Offline.\n");
}

public class IncomingReader implements Runnable{
    @Override
    public void run(){
        String[] data;
        String stream, done = "Done", connect = "Connect", disconnect = "Disconnect", chat = "Chat", shutdown = "Shutdown";

        try{
            while ((stream = in.readLine()) != null){
                 data = stream.split(":");

                 if(data[data.length-1].equals(shutdown)){ 
                    if(data[0].equals("Server")){
                        et_chat.append("Server: The Server is Shutting down!\n");
                    }
                    sendDisconnect();
                    Disconnect();
                 }else if (data[data.length-1].equals(chat)){
                    et_chat.append(data[0] + ": " + extract(stream) + "\n");
                   // et_chat.setCaretPosition(et_chat.getDocument().getLength());
                 }else if (data[data.length-1].equals(connect)){
                    userAdd(data[0]);
                 }else if (data[data.length-1].equals(disconnect)){
                     userRemove(data[0]);
                 }else if (data[data.length-1].equals(done)){
                    users.clear();
                 }
            }
       }catch(Exception ex){ 

       }
    }

    private String extract(String input) {
        for(int i=0;i<input.length();i++){
            if(input.charAt(i) == ':'){
                input =  input.substring(i+1,input.length()-5);
                break;
            }
        } 
        return input;
    }
}


}  

我的root_chat_server代码:

import java.awt.EventQueue;
import java.io.*;
import java.net.*;
import java.util.*;

public class root_Chat_Server{
    private ServerStart serverStart;
    private boolean isStarted = false;
    private Thread starter;

@SuppressWarnings("rawtypes")
ArrayList clientOutputStreams;
@SuppressWarnings("rawtypes")
ArrayList clientHandler;
ArrayList<String> users;
/**
 * Create the application.
 */

 public class ClientHandler implements Runnable{
       BufferedReader reader;
       Socket sock;
       PrintWriter client;

       public ClientHandler(Socket clientSocket, PrintWriter user){
            client = user;
            try{
                sock = clientSocket;
                InputStreamReader isReader = new InputStreamReader(sock.getInputStream());
                reader = new BufferedReader(isReader);
            }
            catch (Exception ex){
                System.out.print("Unexpected error... \n");
            }
       }

       @Override
       public void run(){
            String message, connect = "Connect", disconnect = "Disconnect", chat = "Chat" ;
            String[] data;

            try{
                while ((message = reader.readLine()) != null){
                    System.out.print("Received: " + message + "\n");
                    data = message.split(":");

                    for (String token:data){
                        System.out.print(token + "\n");
                    }

                    if (data[data.length-1].equals(connect)){
                        tellEveryone((data[0] + ":" + data[1] + ":" + chat));
                        userAdd(data[0]);
                    }else if (data[data.length-1].equals(disconnect)){
                        tellEveryone((data[0] + ":has disconnected." + ":" + chat));
                        userRemove(data[0]);
                    }else if (data[data.length-1].equals(chat)){
                        System.out.print("\n\n"+ message +"\n\n");
                        tellEveryone(message);
                    }else{
                        System.out.print("No Conditions were met. \n");
                    }
                } 
             }catch (Exception ex){
                System.out.print("Lost a connection. \n");
                ex.printStackTrace();
                clientOutputStreams.remove(client);
             } 
       }
       public void stop() throws IOException{
           sock.close();
       }
 }

public root_Chat_Server() {

}

private void start(){
    if(!isStarted){
        starter = new Thread(serverStart = new ServerStart());
        starter.start();

        System.out.print("Server started...\n");
        isStarted = true;
    }
}


private void stop(){
    try{
        tellEveryone("Server:Shutdown");
        Thread.sleep(2000);
        serverStart.stop();
        isStarted = false;
    }catch (InterruptedException | IOException ex){
        Thread.currentThread().interrupt();
    }
    System.out.print("Server is stopping...\n\n\n");
}

private void users(){
    System.out.print("\nOnline Users:\n");

    for(String current_users : users){
        System.out.print("-" + current_users + "\n");
    }
}

public class ServerStart implements Runnable{
    ServerSocket serverSock;
    Socket clientSock;
    @SuppressWarnings({ "rawtypes", "unchecked" })
    @Override
    public void run(){
        clientOutputStreams = new ArrayList();
        users = new ArrayList();  
        clientHandler = new ArrayList();
        ClientHandler clientHand;

        try{
            serverSock = new ServerSocket(2222);

            while (true){
                clientSock = serverSock.accept();
                PrintWriter writer = new PrintWriter(clientSock.getOutputStream());
                clientOutputStreams.add(writer);

                Thread listener = new Thread(clientHand = new ClientHandler(clientSock, writer));
                clientHandler.add(clientHand);
                listener.start();
                System.out.print("Got a connection. \n");
            }
        }catch (Exception ex){
            System.out.print("Error making a connection. \n");
        }
    }

    private void stop() throws IOException{
        if(serverSock != null && clientSock != null){
            serverSock.close();
            clientSock.close();
        }else if(serverSock != null){
            serverSock.close();
        }
    }
}

public void userAdd (String data){
    String message, add = ": :Connect", done = "Server: :Done", name = data;
    if(!users.contains(name)){
        System.out.print("Before " + name + " added. \n");
        users.add(name);
        System.out.print("After " + name + " added. \n");
        String[] tempList = new String[(users.size())];
        users.toArray(tempList);

        for (String token:tempList){
            message = (token + add);
            tellEveryone(message);
        }
        tellEveryone(done);
    }else{
        PrintWriter writer = (PrintWriter)clientOutputStreams.get(clientOutputStreams.size()-1);
        ClientHandler clientHand = (ClientHandler)clientHandler.get(clientHandler.size()-1);
        writer.println("Disconnect:Shutdown");
        writer.flush();
        try {
            clientHand.stop();
        } catch (IOException e) {
            e.printStackTrace();
        }
        clientHandler.remove(clientHandler.size()-1);
        clientOutputStreams.remove(clientOutputStreams.size()-1);
    }
}

public void userRemove (String data){
    String message, add = ": :Connect", done = "Server: :Done", name = data;
    users.remove(name);
    String[] tempList = new String[(users.size())];
    users.toArray(tempList);

    for (String token:tempList){
        message = (token + add);
        tellEveryone(message);
    }
    tellEveryone(done);
}

@SuppressWarnings("rawtypes")
public void tellEveryone(String message){
Iterator it = clientOutputStreams.iterator();

    while (it.hasNext()){
        try{
            PrintWriter writer = (PrintWriter) it.next();
            writer.println(message);
            System.out.print("Sending: " + message + "\n");
            writer.flush();
        }catch (Exception ex){
            System.out.print("Error telling everyone. \n");
        }
    } 
}

/**
 * Launch the application.
 */
public static void main(String[] args){
    EventQueue.invokeLater(new Runnable(){
        public void run(){
            if(args.length == 1){
                root_Chat_Server server = new root_Chat_Server();
                if(args[0].equals("start")){
                    server.start();
                }else if(args[0].equals("stop")){
                    server.stop();
                }else if(args[0].equals("users")){
                    server.users();
                }
            }else{
                System.out.println("java root_Chat_Server start|stop|users");
            }
        }
    });
}
}

谢谢你的每一个答案!

2 个答案:

答案 0 :(得分:1)

没有错误,因为您正在捕获异常并打印&#34;无法连接到服务器!再试一次!&#34;。您应该打印异常消息以发现正在发生的事情。

In Android, you have to run asynchronous network operations on a thread other than the main one.您当前正在主线程上运行套接字操作,这将导致异常。

答案 1 :(得分:0)

如果您在项目中使用本机异步时遇到问题。看看这个link。您可以将它用于您的项目。它在带有android客户端的后端Node.js上运行。