关于如何在同一台电脑上的两个安卓模拟器之间的socket通信(图片传输)
2016-10-13 07:33
507 查看
最近课程学习中,遇到了这个问题。 网上搜了一大堆,基本都是抄来抄去的。 即使自己写的,说的也不是很完全。自己第一次用安卓开发,也走了很多弯路。所以写下这篇博客,希望初学者可以少走弯路。本文讲的都是很基础的东西。保证初学者按照步骤来,可以run成功。
开发环境使用的Eclispe,Android SDK 4.2. 开发环境如何搭建就不赘述了。网上太多了。。
课程要求的是在同一台电脑上运行两个AVD(安卓虚拟机), 实现图片传输。从client端传输到server端。
1. 建立一个新的安卓project做为server
Application Name 、Project Name、Package Name 可以随便取。 这里就叫AndroidSocketServer了, 下面的 target SDK
以及 Compile with 都选择 api 17. 如果没有,就选择你自己的sdk. 不一定要api 17. 只是我电脑太老了, 跑
Android 6.0的话
太卡了,AVD 都起不来。 然后就一直next。就可以了。
2.设置main里的参数
在layout中找到main.xml(高版本里好像不叫这个名字),按照如下图设置:
因为在server中我们只需要一个现实一个图片,所以这里控件我们这要加一个ImageView就可以了,注意下
@+id/imageViewServer这个参数, 在后面的server端的程序里会有体现。
3. 在AndroidManifest.xml设置下权限
如下图设置即可,这里我们主要加了五个权限:
4.Server端的代码
</pre><pre name="code" class="java">package com.javacodegeeks.android.androidsocketserver;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.widget.ImageView;
public class Server extends Activity {
private ServerSocket serverSocket;
Handler updateConversationHandler;
Thread serverThread = null;
private ImageView imageView;
public static final int SERVERPORT = 6000;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
imageView=(ImageView) findViewById(R.id.imageViewServer);
updateConversationHandler = new Handler();
this.serverThread = new Thread(new ServerThread());
this.serverThread.start();
}
@Override
protected void onStop() {
super.onStop();
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
class ServerThread implements Runnable {
public void run() {
Socket socket = null;
try {
serverSocket = new ServerSocket(SERVERPORT);
} catch (IOException e) {
e.printStackTrace();
}
while (!Thread.currentThread().isInterrupted()) {
try {
socket = serverSocket.accept();
CommunicationThread commThread = new CommunicationThread(socket);
new Thread(commThread).start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class CommunicationThread implements Runnable {
private Socket clientSocket;
private DataInputStream input;
public CommunicationThread(Socket clientSocket) {
this.clientSocket = clientSocket;
try {
InputStream in = this.clientSocket.getInputStream();
this.input = new DataInputStream(in);
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
byte[] data;//String read = input.readLine();
int len= this.input.readInt();
data = new byte[len];
if (len > 0) {
this.input.readFully(data,0,data.length);
}
updateConversationHa
c51e
ndler.post(new updateUIThread(data));
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class updateUIThread implements Runnable {
private byte[] byteArray;
public updateUIThread(byte[] byteArray) {
this.byteArray = byteArray;
}
@Override
public void run() {
Bitmap bitmap = BitmapFactory.decodeByteArray(byteArray , 0, byteArray .length);
imageView.setImageBitmap(bitmap);
}
}
}
5.建一个client端的project
同server端。
6.main里的参数
这里需要注意的在client端 我们需要两个控件, 一个button 一个 ImageView。因为client端是需要穿图片过去的
所以我们需要指定image的source。我们需要把文件名为image1的图片res-> drawable-hdpi:
7.设置同样的permission
8.client端code
package com.javacodegeeks.android.androidsocketclient;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
public class Client extends Activity {
private Socket socket;
private static final int SERVERPORT = 5000;
private static final String SERVER_IP = "10.0.2.2";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new Thread(new ClientThread()).start();
}
public void onClick(View view) {
try {
ImageView imageView=(ImageView) findViewById(R.id.imageView1);
Bitmap bmp=((BitmapDrawable)imageView.getDrawable()).getBitmap();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bmp.compress(CompressFormat.PNG, 0 /*ignored for PNG*/, bos);
byte[] array = bos.toByteArray();
OutputStream out = socket.getOutputStream();
DataOutputStream dos = new DataOutputStream(out);
dos.writeInt(array.length);
dos.write(array, 0, array.length);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
class ClientThread implements Runnable {
@Override
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
socket = new Socket(serverAddr, SERVERPORT);
} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
9. 启一个AVD做为server端
然后在server的project那右键 Run As -> run configurations. 选择当前的project 以及 server端的AVD。
然后把server端的程序运行在这个AVD上。
10. 重新建一个client端的AVD
和server端一样。 再把client端的程序跑在这个AVD上。注意启动AVD的时候速度会比较慢,如果出现android字样
就说明在启动了,慢慢等就好了。
11. 重定向
在mac终端中输入telnet localhost 5554. 注意这个端口号, 这个是server端的端口号,然后输入 redir add tcp:5000:6000. 对应server端程序和client端程序的端口号,如果提示失败,则说明需要权限。退出来之后,输入
nano ~/.emulator_console_auth_token, 把对应设备的序列号拷贝下来(我的是 kmg2cnUgI2evYbc9),然后进入
之后 auth 加上你的设备序列号即可。 再运行redir add tcp:5000:6000.
12 运行测试
成功。
13. 总结
主要的几个点:
1. 要设置两个main.xml里的控件, 并且控件名称要与程序中的对应。具体的参照我给的程序。
2.在client端中要把图片放到指定的目录下面,并且在client的main.xml中的ImageView中指定相同的文件名。
3.要启动两个AVD,把两个project运行在不同的AVD上面。
4.重定向的端口号要和程序里的对应。
应该没有其他大的问题了,祝大家成功!
开发环境使用的Eclispe,Android SDK 4.2. 开发环境如何搭建就不赘述了。网上太多了。。
课程要求的是在同一台电脑上运行两个AVD(安卓虚拟机), 实现图片传输。从client端传输到server端。
1. 建立一个新的安卓project做为server
Application Name 、Project Name、Package Name 可以随便取。 这里就叫AndroidSocketServer了, 下面的 target SDK
以及 Compile with 都选择 api 17. 如果没有,就选择你自己的sdk. 不一定要api 17. 只是我电脑太老了, 跑
Android 6.0的话
太卡了,AVD 都起不来。 然后就一直next。就可以了。
2.设置main里的参数
在layout中找到main.xml(高版本里好像不叫这个名字),按照如下图设置:
因为在server中我们只需要一个现实一个图片,所以这里控件我们这要加一个ImageView就可以了,注意下
@+id/imageViewServer这个参数, 在后面的server端的程序里会有体现。
3. 在AndroidManifest.xml设置下权限
如下图设置即可,这里我们主要加了五个权限:
4.Server端的代码
</pre><pre name="code" class="java">package com.javacodegeeks.android.androidsocketserver;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.widget.ImageView;
public class Server extends Activity {
private ServerSocket serverSocket;
Handler updateConversationHandler;
Thread serverThread = null;
private ImageView imageView;
public static final int SERVERPORT = 6000;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
imageView=(ImageView) findViewById(R.id.imageViewServer);
updateConversationHandler = new Handler();
this.serverThread = new Thread(new ServerThread());
this.serverThread.start();
}
@Override
protected void onStop() {
super.onStop();
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
class ServerThread implements Runnable {
public void run() {
Socket socket = null;
try {
serverSocket = new ServerSocket(SERVERPORT);
} catch (IOException e) {
e.printStackTrace();
}
while (!Thread.currentThread().isInterrupted()) {
try {
socket = serverSocket.accept();
CommunicationThread commThread = new CommunicationThread(socket);
new Thread(commThread).start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class CommunicationThread implements Runnable {
private Socket clientSocket;
private DataInputStream input;
public CommunicationThread(Socket clientSocket) {
this.clientSocket = clientSocket;
try {
InputStream in = this.clientSocket.getInputStream();
this.input = new DataInputStream(in);
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
byte[] data;//String read = input.readLine();
int len= this.input.readInt();
data = new byte[len];
if (len > 0) {
this.input.readFully(data,0,data.length);
}
updateConversationHa
c51e
ndler.post(new updateUIThread(data));
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class updateUIThread implements Runnable {
private byte[] byteArray;
public updateUIThread(byte[] byteArray) {
this.byteArray = byteArray;
}
@Override
public void run() {
Bitmap bitmap = BitmapFactory.decodeByteArray(byteArray , 0, byteArray .length);
imageView.setImageBitmap(bitmap);
}
}
}
5.建一个client端的project
同server端。
6.main里的参数
这里需要注意的在client端 我们需要两个控件, 一个button 一个 ImageView。因为client端是需要穿图片过去的
所以我们需要指定image的source。我们需要把文件名为image1的图片res-> drawable-hdpi:
7.设置同样的permission
8.client端code
package com.javacodegeeks.android.androidsocketclient;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
public class Client extends Activity {
private Socket socket;
private static final int SERVERPORT = 5000;
private static final String SERVER_IP = "10.0.2.2";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new Thread(new ClientThread()).start();
}
public void onClick(View view) {
try {
ImageView imageView=(ImageView) findViewById(R.id.imageView1);
Bitmap bmp=((BitmapDrawable)imageView.getDrawable()).getBitmap();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bmp.compress(CompressFormat.PNG, 0 /*ignored for PNG*/, bos);
byte[] array = bos.toByteArray();
OutputStream out = socket.getOutputStream();
DataOutputStream dos = new DataOutputStream(out);
dos.writeInt(array.length);
dos.write(array, 0, array.length);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
class ClientThread implements Runnable {
@Override
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
socket = new Socket(serverAddr, SERVERPORT);
} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
9. 启一个AVD做为server端
然后在server的project那右键 Run As -> run configurations. 选择当前的project 以及 server端的AVD。
然后把server端的程序运行在这个AVD上。
10. 重新建一个client端的AVD
和server端一样。 再把client端的程序跑在这个AVD上。注意启动AVD的时候速度会比较慢,如果出现android字样
就说明在启动了,慢慢等就好了。
11. 重定向
在mac终端中输入telnet localhost 5554. 注意这个端口号, 这个是server端的端口号,然后输入 redir add tcp:5000:6000. 对应server端程序和client端程序的端口号,如果提示失败,则说明需要权限。退出来之后,输入
nano ~/.emulator_console_auth_token, 把对应设备的序列号拷贝下来(我的是 kmg2cnUgI2evYbc9),然后进入
之后 auth 加上你的设备序列号即可。 再运行redir add tcp:5000:6000.
12 运行测试
成功。
13. 总结
主要的几个点:
1. 要设置两个main.xml里的控件, 并且控件名称要与程序中的对应。具体的参照我给的程序。
2.在client端中要把图片放到指定的目录下面,并且在client的main.xml中的ImageView中指定相同的文件名。
3.要启动两个AVD,把两个project运行在不同的AVD上面。
4.重定向的端口号要和程序里的对应。
应该没有其他大的问题了,祝大家成功!
相关文章推荐
- 使用socket实现局域网内两个电脑之间图片的收发
- 关于如何在同一台电脑上打开两个myeclipse并分别启动各自自带的tomcat
- 关于socket通信的理解,socket连接通过IP+端口号的方式,那么如果两个服务器端的应用在同一台机器上,并且位于同一个tomcat容器下,那么岂不是两个服务器都收到了客户端发送的信息
- c#2005如何通过socket传输图片
- c#2005如何通过socket传输图片
- 双显示器设置:如何设置一台电脑两个显示器
- android客户端和java服务端之间用socket来传输图片
- C#.NET通过Socket实现平行主机之间网络通讯(含图片传输的Demo演示)
- 一台电脑如何同开两个或多个飞信?
- 双显示器设置:如何设置一台电脑两个显示器
- 如何实现Android两个模拟器之间的通信
- android socket编程——两个模拟器间的通信(一台PC)
- 如何使用ssh(scp, winscp)在N950/N9(MeeGo)与电脑之间传输文件
- 关于socket通信时传输对象
- 如何在一台电脑里装两个操作系统
- C#.NET通过Socket实现平行主机之间网络通讯(含图片传输的Demo演示)
- 关于公网和内网之间Socket的通信
- java socket通信-传输文件图片
- 如何使用飞秋FeiQ实现两电脑通信(或传输文件)
- android客户端和java服务端之间用socket来传输图片