java - 安卓聊天客户端: socket connection

标签 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");
            }
        }
    });
}
}

感谢您的每一个回答!

最佳答案

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

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

关于java - 安卓聊天客户端: socket connection,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35834014/

相关文章:

java - ArrayList元素计数

android - 配置更改时的 fragment 重建

Android蓝牙socket非阻塞通信教程

c - FTP 实现 : close data socket every time

java - android:以编程方式更改选项菜单项

java - Jsoup 设置接受 header 请求不起作用

java - JDBCRealm 与 JPA

c# - 使用 Unity3d 连接到 MySQL 服务器?

java - 在 Activity 之间交换数据的另一种方式

javascript - socket.io 上的 CORS 问题