chiakikuro 2018-06-11 00:51 采纳率: 100%
浏览 3506
已采纳

Android socket通讯客户端连不上服务器问题,以及发送消息程序就闪退

原本以为是线程问题但是好像又不是,实在找不到怎么弄了
这是客户端:
package com.chiaki.mysocketobject;

import android.content.Intent;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.TextView;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

public class ChatActivity extends AppCompatActivity implements Runnable{

private static final String HOST = "172.16.2.54";
private static final int PORT = 12345;

private MsgAdapter adapter;
private ListView msgListView;
private List<Msg> msgList=new ArrayList<Msg>();

private  ImageButton send;
private  ImageButton connect;
private  EditText edit;
private TextView ctext;

private Socket socket;
private BufferedReader in = null;
private PrintWriter out = null;
private String content = "";
private StringBuilder sb = null;

public Handler handler = new Handler() {
    public void handleMessage(Message msg) {
        if (msg.what == 0x123) {
            sb.append(content);
            ctext.setText(sb.toString());
        }
    }
};

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

    adapter=new MsgAdapter(ChatActivity.this,R.layout.chat_list_view,msgList);

    ImageButton back = (ImageButton)findViewById(R.id.back);
    ImageButton voiceButton = (ImageButton)findViewById(R.id.voiceButton);
    connect = (ImageButton)findViewById(R.id.connectButton);
    send = (ImageButton)findViewById(R.id.send);
    edit = (EditText)findViewById(R.id.edit);
    ctext = (TextView)findViewById(R.id.chattext);
    msgListView=(ListView)findViewById(R.id.msg_list_view);
    sb = new StringBuilder();
    msgListView.setAdapter(adapter);

    // 点击按钮实例化Socket对象,与服务端进行连接,获取输入输出流
    // 连接服务器,要在子线程中
    connect.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            new Thread() {
                @Override
                public void run() {
                    super.run();
                    try {
                        // 创建socket,连接服务器
                        socket = new Socket(HOST, PORT);//连接服务器
                        in = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));//接收消息的流对象
                        out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);//发送消息的流对象
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }.start();
        }
    });

    back.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(ChatActivity.this,SocketActivity.class);
            startActivity(intent);
        }
    });

    send.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            String con=edit.getText().toString();
            edit.setText("");
            if (socket.isConnected()) {
                if (!socket.isOutputShutdown()) {
                        out.println(con);//点击按钮发送消息
                }
            }
        }
    });
    //启动线程,连接服务器,并用死循环守候,接收服务器发送过来的数据
    new Thread(ChatActivity.this).start();
}

// 重写run方法,在该方法中输入流的读取
public void run() {
    try {
        while (true) {                 //死循环守护,监控服务器发来的消息
            if (socket.isConnected()) {           //如果服务器没有关闭
                if (!socket.isInputShutdown()) {          //连接正常
                    if ((content = in.readLine()) != null) {    //如果输入流没有断开
                        content += "\n";                    //读取接收的信息
                        handler.sendEmptyMessage(0x123);   //会发送一个空消息,但是指定了Message的what属性
                    }
                }
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

}

这是layout文件主要的控件:
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="@android:drawable/checkbox_on_background"
android:id="@+id/connectButton"
android:layout_alignParentStart="true"
android:layout_below="@+id/edit" />

    <TextView                               //显示消息
        android:text="TextView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/chattext" />

    <ImageButton                                           //编辑消息
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:srcCompat="@android:drawable/ic_btn_speak_now"
    android:id="@+id/voiceButton"
    android:layout_below="@+id/edit"
    android:layout_centerHorizontal="true" />

<ImageButton                                         //发送消息
    android:layout_width="wrap_content"
    android:layout_height="40dp"
    app:srcCompat="@android:drawable/ic_menu_send"
    android:id="@+id/send"
    android:backgroundTint="?attr/colorButtonNormal"
    android:layout_alignParentBottom="true"
    android:layout_alignParentEnd="true" />

这是服务端:
import java.io.DataInputStream;
import java.io.BufferedReader;

import java.io.BufferedWriter;

import java.io.IOException;

import java.io.InputStreamReader;

import java.io.OutputStreamWriter;

import java.io.PrintWriter;

import java.net.ServerSocket;

import java.net.Socket;

import java.util.ArrayList;

import java.util.List;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
// 定义相关的参数,端口,存储Socket连接的集合,ServerSocket对象

// 以及线程池

private static final int PORT = 12345;

private List mList = new ArrayList();

private ServerSocket server = null;

private ExecutorService myExecutorService = null;

public static void main(String[] args) {

new Server();

}

public Server() {  
    try {  
        server = new ServerSocket(PORT);  
        // 创建线程池  
        myExecutorService = Executors.newCachedThreadPool();  
        System.out.println("服务端运行中...\n");  
        Socket client = null;  
        while (true) {  
            client = server.accept();  
            mList.add(client);  
            myExecutorService.execute(new Service(client));  
        }  

    } catch (Exception e) {  
        e.printStackTrace();  
    }  
}  

class Service implements Runnable {  
    private Socket socket;  
    private BufferedReader in = null;  
    private String msg = "";  

    public Service(Socket socket) {  
        this.socket = socket;  
        try {  
            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));  
            System.out.println("用户:" + this.socket.getInetAddress() + "~加入了聊天室" + "当前在线人数:" + mList.size()); 
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
    }  

    @Override  
    public void run() {  
        try {  
            while (true) {  
                if ((msg = in.readLine()) != null) {  
                    if (msg.equals("bye")) {  
                        System.out.println("~~~~~~~~~~~~~");  
                        mList.remove(socket);  
                        in.close();  
                        System.out.println("用户:" + socket.getInetAddress() + "退出:" + "当前在线人数:" + mList.size());
                        socket.close();  
                        break;  
                    } else {
                        System.out.println(socket.getInetAddress() + "  说: " + msg);
                        this.sendmsg();
                    }  
                }  
            }  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  

    // 为连接上服务端的每个客户端发送信息  
    public void sendmsg() {   
        int num = mList.size();  
        for (int index = 0; index < num; index++) {  
            Socket mSocket = mList.get(index);  
            PrintWriter pout = null;  
            try {  
                pout = new PrintWriter(
                        new BufferedWriter(new OutputStreamWriter(mSocket.getOutputStream(), "UTF-8")), true);  
                pout.println(msg);  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
        }  
    }  
} 

}

  • 写回答

7条回答 默认 最新

  • JabamiLight 2018-06-11 01:56
    关注

    你这个很可能是ArrayList的线程安全问题造成的,多线程同时操作,没有进行同步就很容易出现异常。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(6条)

报告相同问题?

悬赏问题

  • ¥15 多尺度特征图提取和融合
  • ¥15 微信小程序:渲染收货地址时页面不显示
  • ¥20 win7 64位DirectShow提示初始化失败如何解决?
  • ¥20 小规模孤立词识别系统设计
  • ¥15 关于Java对接海康威视车牌识别一体机SDK是否需要固定外网的IP?
  • ¥15 Linux扩容时,格式化卡住了:vgdispaly查看卷组信息,没有输出
  • ¥18 关于#ubuntu#的问题:使用背景-工作职责内有七八台ubuntu系统的电脑,平时需要互相调取资料,想实现把这几台电脑用交换机组成一个局域网,来实现指定文件夹的互相调取和写入
  • ¥20 求一个简易射频信号综测仪
  • ¥15 esp8266 tally灯 接收端改为发射端
  • ¥30 Labview代码调用access 数据库,相同代码其中一个调用不出来是为什么