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
阅读全文
0 0
- Android:Socket连接传输
- socket连接及传输机制
- android socket传输
- android socket对象传输
- android socket 传输示例
- Android-Socket传输 GPRS网络
- Android-Socket基于UDP传输
- socket使用代理连接以及传输对象
- socket连接传输对象无响应
- Android蓝牙连接,传输数据
- Android socket 连接通信
- android socket连接状态
- android socket 长连接
- android socket长连接
- android socket长连接
- Android之Socket的基于UDP传输
- Android之Socket的基于UDP传输
- Android之Socket的基于UDP传输
- sql的左联接
- PHP-FPM进程数的设定
- postgresql 授权某个数据库的权限给test 账号 使该账号 只能操作指定DB 不能操作其他DB
- Bash基本命令整理
- 微信开发的各种坑
- Android:Socket连接传输
- Spring Bean设置别名的两种方式
- Linux常用性能分析工具
- fzu 2230
- 字符编码(哈夫曼编码)
- 安信可A7模块GPS定位功能测试及解析
- linux学习之pxe
- 乱码
- 约瑟夫环问题