2016-03-06 79 views
1

即时通讯新的Android。首先,我用Java编写了一个Chat_Client和Server。它效果很好。Android聊天客户端:套接字连接

然后我试图将其转换为一个可用的Android应用程序,我总是收到消息“无法连接到服务器!再试一次!”所以它显然是错误的连接尝试,但我不知道它是什么。

背景知识:
- 我连接到我的根服务器,并看看聊天服务器进程。它正在运行!
- 我尝试从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"); 
      } 
     } 
    }); 
} 
} 

谢谢每一个答案!

回答

1

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

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

+0

非常感谢你的回答。我只是把连接部分从onCreate放到IncomingReader.run()线程中。现在我得到了一个连接和一个新的问题...我看到服务器收到我发送的消息,但它不会将其发送回客户端... – Voldemord

0

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