java socket服务器与安卓多客户端通信

本文详细介绍了如何从零开始搭建一个简单的Socket服务端和安卓客户端,包括服务端的启动与监听,客户端的UI设计及连接逻辑。通过实例代码,展示了数据收发流程,适合初学者快速上手。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先我们建立服务端,


public class Main {

    public static void main(String[] args){
        //启动socket服务
        try{
            final ServerSocket server = new ServerSocket(8888);
            System.out.println("服务器已经启动" + server);
            while(true){
                // 服务器接收到链接进来的客户端
                Socket socket = server.accept();
                System.out.println("有客户端链接进来" + socket);
                new Thread(new SocketTast(socket)).start();
            }
        }catch (IOException e){
            e.printStackTrace();
        }

    }

    static class SocketTast implements Runnable{

        private Socket socket;

        public SocketTast(Socket socket){
            this.socket = socket;
        }

        @Override
        public void run(){
            try {

                while (true) {
                    // 处理接收到的数据
                    // 获取输入流,打印客户端信息
                    InputStream inputStream = socket.getInputStream();
                    InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
                    BufferedReader in = new BufferedReader(inputStreamReader);
                    String getinput = in.readLine();
                    if(getinput != null){
                        System.out.println(socket + ":" + getinput);
                        getinput = null;
                    }
                }
            }catch (IOException e){
                e.printStackTrace();
            }
        }
    }
}

然后建立安卓客户端

 

xml

<RelativeLayout
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    tools:layout_editor_absoluteY="25dp">

    <EditText
        android:id="@+id/client_ip"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_marginStart="7dp"
        android:layout_marginTop="370dp"
        android:layout_marginEnd="11dp"
        android:layout_toStartOf="@+id/textView2"
        android:ems="10"
        android:hint="@string/edit_ip"
        android:inputType="textPersonName"
        android:text="@string/ip" />

    <Button
        android:id="@+id/join"
        android:layout_width="126dp"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:layout_marginStart="7dp"
        android:layout_marginTop="506dp"
        android:text="@string/link" />

    <EditText
        android:id="@+id/port"
        android:layout_width="108dp"
        android:layout_height="wrap_content"
        android:layout_above="@+id/edit_msg"
        android:layout_alignParentTop="true"
        android:layout_alignParentEnd="true"
        android:layout_marginTop="371dp"
        android:layout_marginEnd="20dp"
        android:layout_marginBottom="21dp"
        android:ems="10"
        android:hint="@string/edit_port"
        android:inputType="textPersonName"
        android:text="@string/port" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="15dp"
        android:layout_height="41dp"
        android:layout_alignParentTop="true"
        android:layout_marginTop="373dp"
        android:layout_marginEnd="8dp"
        android:layout_toStartOf="@+id/port"
        android:text=":"
        android:textSize="30dp" />

    <TextView
        android:id="@+id/msg"
        android:layout_width="match_parent"
        android:layout_height="344dp"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:layout_marginStart="0dp"
        android:layout_marginTop="8dp" />

    <EditText
        android:id="@+id/edit_msg"
        android:layout_width="374dp"
        android:layout_height="wrap_content"
        android:layout_above="@+id/send"
        android:layout_alignStart="@+id/client_ip"
        android:layout_marginStart="3dp"
        android:layout_marginBottom="22dp"
        android:ems="10"
        android:hint="@string/edit_msg_hint"
        android:inputType="textPersonName" />

    <Button
        android:id="@+id/send"
        android:layout_width="111dp"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_marginStart="14dp"
        android:layout_marginEnd="13dp"
        android:layout_marginBottom="14dp"
        android:layout_toStartOf="@+id/clear"
        android:layout_toEndOf="@+id/join"
        android:text="@string/send_msg" />

    <Button
        android:id="@+id/clear"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:layout_alignTop="@+id/join"
        android:layout_alignEnd="@+id/port"
        android:layout_marginTop="0dp"
        android:layout_marginEnd="-7dp"
        android:text="@string/message_clear" />

</RelativeLayout>

java


public class MainActivity extends AppCompatActivity  {

    private TextView get_msg;   //声明接收文本框
    private EditText ed_msg,c_ip,c_port;   //声明消息,ip,端口编辑框
    private Button send_msg,join,clear_msg;          //声明发送信息按钮、连接按钮与消息清除按钮
    private Socket socket = null;
    private  BufferedReader in;             //声明输入流
    private OutputStream outputStream;      //输出流
    private Thread connectthread,send;              //声明连接线程与发送线程
    private boolean isconnect = false;    //声明连接状态
    private Runnable connection;




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

        get_msg = findViewById(R.id.msg);
        ed_msg = findViewById(R.id.edit_msg);
        send_msg = findViewById(R.id.send);
        c_ip = findViewById(R.id.client_ip);
        c_port = findViewById(R.id.port);
        join = findViewById(R.id.join);
        clear_msg = findViewById(R.id.clear);


        join.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (!isconnect) {      //当连接关闭时连接
                    connectthread=new Thread(connection);
                    connectthread.start();       //启动连接线程
                }
                else {  //当再次点击时关闭连接
                    isconnect = false;          //更新连接状态为关闭
                    try {
                        if (socket.isConnected()) {   //检查连接状态
                            //先关闭socket连接,再关闭输入流,输出流
                            socket.close();
                            socket = null;
                            in.close();
                            outputStream.close();
                            Toast.makeText(MainActivity.this, "断开连接!",Toast.LENGTH_SHORT).show();
                            join.setText("连接");
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    //中断连接线程
                    connectthread.interrupt();

                }
            }
        });

        send_msg.setOnClickListener(new View.OnClickListener() {  //发送数据
            @Override
            public void onClick(View v) {
                send = new Thread() {
                    public void run() {
                        try {
                            outputStream.write((ed_msg.getText().toString() + "\n").getBytes("utf-8"));//输出流以utf-8发送数据。
                            outputStream.flush();
                            get_msg.setText(get_msg.getText() + "\rclient: " + ed_msg.getText().toString() + "\n");  //在控件中显示发送的数据。
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                };
                send.start();
            }
        });

        /*
        线程用于连接和接收消息并显示
         */
        connection = new Runnable() {
            @Override
            public void run() {
                try {
                    socket = new Socket(c_ip.getText().toString(), Integer.parseInt(c_port.getText().toString()));  //建立socket,并获取端口,ip
                    in = new BufferedReader(new InputStreamReader(socket.getInputStream()));   //读取输入流
                    outputStream = socket.getOutputStream();   //输出流
                    if (socket.isConnected()) {    //如果连接成功就让按钮显示断开
                        join.setText("断开");             //更新连接按钮显示
                        isconnect = true;          //更新连接状态为连接
                    }
                    String Data = "";
                    while (true) {
                        Data =  in.readLine();  //使用readLine()时服务端发送消息应当以“\n”结尾表示数据发送结束。
                        get_msg.setText(get_msg.getText() + "\rservice: "+Data+"\n");
                    }
                } catch (UnknownHostException e1){
                    e1.printStackTrace();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        };

        clear_msg.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                get_msg.setText("");
            }
        });


    }
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值