Android:Socket连接传输

来源:互联网 发布:笛佛软件招聘 编辑:程序博客网 时间:2024/05/16 17:09

前言:

刚写完蓝牙间通信的一个小DEMO,顺势再试一下Socket间的通信。实现的功能和蓝牙的一样,连接之后拍照通过二进制流传输图片。

1)程序需要两台设备连接同一局域网的WIFI才能连接

2)SDK和系统版本的差异这里没做什么测试,大家对这一点是很有经验的了


一.服务端

1)约定一个端口号,再建立一个服务端的Socket,开辟线程循环监听,等待客户端的链接。

2)输入流同样需要在一个线程中操作,关于输入流的读取和蓝牙中一样,约定前4个字节为数据的长度,根据这个为数据读取结束的标志。

3)输出流这里和蓝牙中有点不同,需要在新的线程中写数据,否则会报NetworkRunOnUiThread的错误。

public class MainActivity extends AppCompatActivity {    private final int PORT = 9999;    private ServerSocket serverSocket;    private ReadThread thread;    private ConnectThread connectThread;    private Button btSend;    private Button btRead;    private EditText edtSend;    private ImageView imgView;    private InputStream is;    private OutputStream os;    private final String TAG = "Socket";    private Socket client = null;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        btSend = (Button) findViewById(R.id.bt_send);        imgView = (ImageView) findViewById(R.id.img);        btSend.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);                startActivityForResult(intent,                        100);            }        });        thread = new ReadThread();        thread.start();        connectThread = new ConnectThread();        connectThread.start();    }    private class ConnectThread extends Thread {        @Override        public void run() {            super.run();            try {                serverSocket = new ServerSocket(PORT);                while (true) {                    if (serverSocket != null) {                        client = serverSocket.accept();                        is = client.getInputStream();                        os = client.getOutputStream();                    }                }            } catch (Exception e) {            }        }    }    private String intToIp(int i) {        return (i & 0xFF) + "." +                ((i >> 8) & 0xFF) + "." +                ((i >> 16) & 0xFF) + "." +                (i >> 24 & 0xFF);    }    @Override    protected void onActivityResult(int requestCode, int resultCode, Intent data) {        super.onActivityResult(requestCode, resultCode, data);        if (requestCode == 100                && resultCode == Activity.RESULT_OK) {            Bundle bundle = data.getExtras();            Bitmap map = (Bitmap) bundle.get("data");            ByteArrayOutputStream baos = new ByteArrayOutputStream();            map.compress(Bitmap.CompressFormat.JPEG, 10, baos);            final byte[] picData = baos.toByteArray();            Thread thread = new Thread(new Runnable() {                @Override                public void run() {                    if (client.isConnected() && os != null) {                        try {                            os.write(intToBytes(picData.length));                            os.write(picData);                            os.flush();                        } catch (IOException e) {                            e.printStackTrace();                        }                    }                }            });            thread.start();        }    }    private class ReadThread extends Thread {        @Override        public void run() {            super.run();            while (true) {                if (is != null) {                    try {                        final byte[] buffer = readStream(is);                        if (buffer != null && buffer.length > 0) {                            runOnUiThread(new Runnable() {                                @Override                                public void run() {                                    if (imgView != null) {                                        imgView.setImageBitmap(BitmapFactory.decodeByteArray(buffer, 0, buffer.length));                                    }                                }                            });                        }                    } catch (Exception e) {                    }                }            }        }    }    public static byte[] intToBytes(int value) {        byte[] src = new byte[4];        src[3] = (byte) ((value >> 24) & 0xFF);        src[2] = (byte) ((value >> 16) & 0xFF);        src[1] = (byte) ((value >> 8) & 0xFF);        src[0] = (byte) (value & 0xFF);        return src;    }    public static int bytesToInt(byte[] src, int offset) {        int value;        value = (int) ((src[offset] & 0xFF)                | ((src[offset + 1] & 0xFF) << 8)                | ((src[offset + 2] & 0xFF) << 16)                | ((src[offset + 3] & 0xFF) << 24));        return value;    }    public static byte[] readStream(InputStream inStream) throws Exception {        if (inStream.available() <= 0)            return null;        byte[] head = new byte[4];        byte[] buffer = new byte[1024];        int len = -1;        int length = 0;        inStream.read(head);        int scrLength = bytesToInt(head, 0);        ByteArrayOutputStream outStream = new ByteArrayOutputStream();        while ((len = inStream.read(buffer)) != -1) {            length = length + len;            outStream.write(buffer, 0, len);            if (length >= scrLength)                break;        }        byte[] data = outStream.toByteArray();        outStream.close();        return data;    }}


二.客户端

1)客户端除了需要知道约定的端口号之外还需要知道服务端的IP地址(可以在手机系统信息中查看,也可以通过代码得到)

2)其余的逻辑跟服务端差不多

public class MainActivity extends AppCompatActivity {    private final String HOST = "192.168.0.104";    private final int PORT = 9999;    private Socket socket;    private InputStream is;    private OutputStream os;    private ReadThread thread;    private Button btSend;    private Button btRead;    private EditText edtSend;    private ImageView imgView;    private final String TAG = "Socket";    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        btSend = (Button) findViewById(R.id.button1);        imgView = (ImageView) findViewById(R.id.img);        if (btSend != null) {            btSend.setOnClickListener(new View.OnClickListener() {                @Override                public void onClick(View view) {                    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);                    startActivityForResult(intent,                            100);                }            });        }        ConnectThread connectThread = new ConnectThread();        connectThread.start();        thread = new ReadThread();        thread.start();    }    private class ConnectThread extends Thread {        @Override        public void run() {            super.run();            try {                socket = new Socket(HOST, PORT);                is = socket.getInputStream();                os = socket.getOutputStream();            } catch (Exception e) {                e.printStackTrace();            }        }    }    private class ReadThread extends Thread {        byte[] buffer = null;        @Override        public void run() {            super.run();            while (true) {                try {                    if (socket != null && socket.isConnected() && is != null && is.available() > 0) {                        final byte[] buffer = readStream(is);                        if (buffer != null && buffer.length > 0) {                            runOnUiThread(new Runnable() {                                @Override                                public void run() {                                    if (imgView != null) {                                        imgView.setImageBitmap(BitmapFactory.decodeByteArray(buffer, 0, buffer.length));                                    }                                }                            });                        }                    }                } catch (Exception e) {                }            }        }    }    public static byte[] readStream(InputStream inStream) throws Exception {        if (inStream.available() <= 0)            return null;        byte[] head = new byte[4];        byte[] buffer = new byte[1024];        int len = -1;        int length = 0;        inStream.read(head);        int scrLength = bytesToInt(head, 0);        ByteArrayOutputStream outStream = new ByteArrayOutputStream();        while ((len = inStream.read(buffer)) != -1) {            length = length + len;            outStream.write(buffer, 0, len);            if (length >= scrLength)                break;        }        byte[] data = outStream.toByteArray();        outStream.close();        return data;    }    @Override    protected void onActivityResult(int requestCode, int resultCode, Intent data) {        super.onActivityResult(requestCode, resultCode, data);        if (requestCode == 100                && resultCode == Activity.RESULT_OK) {            Bundle bundle = data.getExtras();            Bitmap map = (Bitmap) bundle.get("data");            ByteArrayOutputStream baos = new ByteArrayOutputStream();            map.compress(Bitmap.CompressFormat.JPEG, 10, baos);            final byte[] picData = baos.toByteArray();            Thread thread = new Thread(new Runnable() {                @Override                public void run() {                    if (socket.isConnected() && os != null) {                        try {                            os.write(intToBytes(picData.length));                            os.write(picData);                            os.flush();                        } catch (IOException e) {                            e.printStackTrace();                        }                    }                }            });            thread.start();        }    }    public static byte[] intToBytes(int value) {        byte[] src = new byte[4];        src[3] = (byte) ((value >> 24) & 0xFF);        src[2] = (byte) ((value >> 16) & 0xFF);        src[1] = (byte) ((value >> 8) & 0xFF);        src[0] = (byte) (value & 0xFF);        return src;    }    public static int bytesToInt(byte[] src, int offset) {        int value;        value = (int) ((src[offset] & 0xFF)                | ((src[offset + 1] & 0xFF) << 8)                | ((src[offset + 2] & 0xFF) << 16)                | ((src[offset + 3] & 0xFF) << 24));        return value;    }}

源码下载,这里只给出主要的类和布局,大家最好自己构建项目,就不会有这么多编译上的问题。

https://github.com/SingleInstance/Socket-for-Android

原创粉丝点击