在android的同一个wifi局域网下,利用socket与多个手机进行数据的收发

前言:

在这里强调局域网,是因为内网之间的设备通信时,无需经过外网,若想内网的设备能够与外网进行通信,可自行百度其解决办法...

虽说利用wifi,实质是怎么利用socket来进行通信的问题


步骤一:编写服务端和客户端的代码

服务端代码(MainActivity.java):

package com.example.dai.wifiserver;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.widget.EditText;
import android.widget.TextView;

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class MainActivity extends AppCompatActivity {

    private TextView editText_1;
    private EditText editText_2;
    private ServerSocket serverSocket = null;
    StringBuffer stringBuffer = new StringBuffer();

    private InputStream inputStream;

    public Handler handler = new Handler(){

        @Override
        public void handleMessage(Message msg) {

            switch (msg.what){
                case 1:
                    editText_1.setText(msg.obj.toString());
                    break;
                case 2:
                    editText_2.setText(msg.obj.toString());
                    stringBuffer.setLength(0);
                    break;

            }

        }
    };

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

        editText_1 = (TextView) findViewById(R.id.et_1);
        editText_2 = (EditText) findViewById(R.id.et_2);

        receiveData();
    }

    /*
    服务器端接收数据
    需要注意以下一点:
    服务器端应该是多线程的,因为一个服务器可能会有多个客户端连接在服务器上;
    */
    public void receiveData(){

        Thread thread = new Thread(){
            @Override
            public void run() {
                super.run();
                /*指明服务器端的端口号*/
                try {
                    serverSocket = new ServerSocket(8000);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                
                GetIpAddress.getLocalIpAddress(serverSocket);

                Message message_1 = handler.obtainMessage();
                message_1.what = 1;
                message_1.obj = "IP:" + GetIpAddress.getIP() + " PORT: " + GetIpAddress.getPort();
                handler.sendMessage(message_1);

                while (true){
                    Socket socket = null;
                    try {
                      socket = serverSocket.accept();
                      inputStream  = socket.getInputStream();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                    new ServerThread(socket,inputStream).start();

                }
            }
        };
        thread.start();

    }

    class ServerThread extends Thread{

        private Socket socket;
        private InputStream   inputStream;
        private StringBuffer stringBuffer = MainActivity.this.stringBuffer;


        public ServerThread(Socket socket,InputStream inputStream){
            this.socket = socket;
            this.inputStream = inputStream;
        }

        @Override
        public void run() {
            int len;
            byte[] bytes = new byte[20];
            boolean isString = false;

            try {
                //在这里需要明白一下什么时候其会等于 -1,其在输入流关闭时才会等于 -1,
                //并不是数据读完了,再去读才会等于-1,数据读完了,最结果也就是读不到数据为0而已;
                while ((len = inputStream.read(bytes)) != -1) {
                    for(int i=0; i; i++){
                        if(bytes[i] != '\0'){
                            stringBuffer.append((char)bytes[i]);
                        }else {
                            isString = true;
                            break;
                        }
                    }
                    if(isString){
                        Message message_2 = handler.obtainMessage();
                        message_2.what = 2;
                        message_2.obj = stringBuffer;
                        handler.sendMessage(message_2);
                        isString = false;
                    }

                }
                //当这个异常发生时,说明客户端那边的连接已经断开
            } catch (IOException e) {
                e.printStackTrace();
                try {
                    inputStream.close();
                    socket.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }

            }

        }
    }


    /*当按返回键时,关闭相应的socket资源*/
    @Override
    public void onBackPressed() {
        super.onBackPressed();
        try {
            serverSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}


GetIpAddress.java:

package com.example.dai.wifiserver;

import android.util.Log;

import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.ServerSocket;
import java.net.SocketException;
import java.util.Enumeration;

public class GetIpAddress {
   
   public static String IP;
   public static int PORT;
   
   public static String getIP(){
      return IP;
   }
   public static int getPort(){
      return PORT;
   }
   public static void getLocalIpAddress(ServerSocket serverSocket){

      try {
         for (Enumeration en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();){
                NetworkInterface intf = en.nextElement();
                for (Enumeration enumIpAddr = intf.getInetAddresses();    enumIpAddr.hasMoreElements();){
                    InetAddress inetAddress = enumIpAddr.nextElement();
                    String mIP = inetAddress.getHostAddress().substring(0, 3);
                    if(mIP.equals("192")){
                        IP = inetAddress.getHostAddress();    //获取本地IP
                        PORT = serverSocket.getLocalPort();    //获取本地的PORT
                        Log.e("IP",""+IP);
                        Log.e("PORT",""+PORT);
                    }
                }
            }
      } catch (SocketException e) {
         e.printStackTrace();
      }

   }
}


客户端代码:

package com.example.dai.wificlient;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;

public class MainActivity extends AppCompatActivity {

    private EditText editText_ip,editText_data;
    private OutputStream outputStream = null;
    private Socket socket = null;
    private String ip;
    private String data;
    private boolean socketStatus = false;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        editText_ip = (EditText) findViewById(R.id.et_ip);
        editText_data = (EditText) findViewById(R.id.et_data);

    }


    public void connect(View view){

        ip = editText_ip.getText().toString();
        if(ip == null){
            Toast.makeText(MainActivity.this,"please input Server IP",Toast.LENGTH_SHORT).show();
        }

        Thread thread = new Thread(){
            @Override
            public void run() {
                super.run();

                if (!socketStatus) {

                    try {
                        socket = new Socket(ip,8000);
                        if(socket == null){
                        }else {
                            socketStatus = true;
                        }
                        outputStream = socket.getOutputStream();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                }

            }
        };
        thread.start();

    }


    public void send(View view){

        data = editText_data.getText().toString();
        if(data == null){
            Toast.makeText(MainActivity.this,"please input Sending Data",Toast.LENGTH_SHORT).show();
        }else {
            //在后面加上 '\0' ,是为了在服务端方便我们去解析;
            data = data + '\0';
        }

        Thread thread = new Thread(){
            @Override
            public void run() {
                super.run();
                if(socketStatus){
                    try {
                        outputStream.write(data.getBytes());
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                }

            }
        };
        thread.start();

    }

    /*当客户端界面返回时,关闭相应的socket资源*/
    @Override
    public void onBackPressed() {
        super.onBackPressed();
        /*关闭相应的资源*/
        try {
            outputStream.close();
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
}


步骤二:

将服务端app下载至其中一台android设备,将客户端下载至另一台android设备,然后先开启服务端程序,最后再开启客户端程序


测试效果图如下:

服务端:

在android的同一个wifi局域网下,利用socket与多个手机进行数据的收发_第1张图片


客户端:

在android的同一个wifi局域网下,利用socket与多个手机进行数据的收发_第2张图片



服务端源码:

请点击这里


客户端源码:

请点击这里


关注微信公众号获取更多资讯

在android的同一个wifi局域网下,利用socket与多个手机进行数据的收发_第3张图片


你可能感兴趣的:(Android应用开发基础篇)