android socket双向,【笔记】两台Android手机的Socket双向通信

上学期搞定了小车,现在终于结束了大机器人,趁还没真正进入考研复习的高潮赶紧把以前的代码整理整理。

先讲讲我们那小车,2台手机+车体组成。一个手机放车上作为server,用其摄像头、陀螺仪、磁力计来获取图像、确定小车方向。另一台手机负责控制,作为client,并画出小车行进图。如何从server获取陀螺仪、磁力计角度,又如何把client的控制命令发送给server就成了一个问题。这里我们使用socket双向通信。

先讲client部分

// Socket Client connect to Server

connectButton.setOnClickListener(new Button.OnClickListener()

{

@Override

public void onClick(View v)

{

// TODO Auto-generated method stub

try

{

ip = mEditText02.getText().toString();

Thread thread = new Thread(new mSocketConnectRunnable2());

thread.start();

// thread.sleep(100);

goToControl(); //进行控制命令的处理

connectButton.setVisibility(View.INVISIBLE);

mEditText02.setVisibility(View.INVISIBLE);

}

catch (Exception e)

{

e.printStackTrace();

}

}

});

两台手机都连接到同个wifi,这个就不多讲了。首先你得有个EditText填写server的IP地址,然后有个按钮,点击启动个线程,负责与server通信,这里传给Thread的构造函数调用Runnable接口。socket其实就是对某一个服务器的一个端口进行连接,连接上后就形成会话。由于这里socket是全双向的字节流,所以连上的时候其本身就已经具备了双向通信能力。

然后我们看它调用的接口,怎么连接和接受server发来的数据……

//Socket Client

public class mSocketConnectRunnable2 implements Runnable

{

@Override

public void run()

{

try

{

mSocket02 = new Socket(ip, intSocketServerPort);

if(mSocket02.isConnected())

{

Log.i(TAG, "Socket Client is connected to Server.");

strTemp01="Socket Client is connected to Server.";

}

BufferedReader br = new BufferedReader(new InputStreamReader(mSocket02.getInputStream()));

while (true)

{

strTemp01 = br.readLine();

if(!strTemp01.isEmpty())

handler.post(rReceiveInfo);

}

}

catch(Exception e)

{

if(bIfDebug)

{

Log.e(TAG, e.toString());

e.printStackTrace();

}

}

}

}

ip上面说了,intSocketServerPort是socket端口,我这里设置为8080。mSocket02就像个水管,可以往里灌水也可以抽水。这里通过BufferedReader获得字节流,用handler传递进行数据处理。这里推荐用handler,不仅增加代码可度性,更容易避免莫名其妙的bug……

以上是建立socket连接并且从server获取字节流的过程,下面是发送字节流的部分……

public static void action(String a){

//当Socket连接正常且不为空时,流输出给server

if(mSocket02!=null && mSocket02.isConnected() && !a.equals(""))

{

try

{

bw = new BufferedWriter(new OutputStreamWriter(mSocket02.getOutputStream()));

bw.write(a+"\n");

bw.flush();

}

catch (Exception e)

{

Log.e(TAG, e.toString());

e.printStackTrace();

}

}

}

这里,比如我用 action("forward"),则字节流将forward发往server,至于这里流输出,不过多解释,详细的需要自己仔细查看socket。

然后是server部分……这里我们设置一个按钮用于开启socket server

// Run Socket Server

mButton01.setOnClickListener(new Button.OnClickListener()

{

@Override

public void onClick(View v)

{

// TODO Auto-generated method stub

mButton01.setEnabled(false);

mButton02.setEnabled(true);

setContentView(R.layout.i3);

Thread thread = new Thread(new mSocketConnectRunnable1());

thread.start();

}

});

这里也是用Thread的构造函数调用Runnable接口

//Socket Server

public class mSocketConnectRunnable1 implements Runnable

{

@Override

public void run()

{

// TODO Auto-generated method stub

try

{

mServerSocket01 = new ServerSocket(intSocketServerPort);

mServerSocket01.setReuseAddress(true);

Log.i(TAG, strDebugPreFix+"Socket Server is Running: "+intSocketServerPort);

while (!mServerSocket01.isClosed())

{

mSocket01 = mServerSocket01.accept();

Thread read = new Thread(new Runnable()

{

BufferedReader br = new BufferedReader(new InputStreamReader(mSocket01.getInputStream()));

@Override

public void run()

{

try

{

while (mSocket01.isConnected())

{

msg = br.readLine();

Handler01.post(rManualControl);

}

}

catch (Exception e)

{

if(bIfDebug)

{

Log.e(TAG, e.toString());

e.printStackTrace();

}

}

}

});

read.start();

//在接受数据的同时发送数据,实现双向通信

Thread write = new Thread (new Runnable()

{

@Override

public void run()

{

while (mSocket01.isConnected())

{

try

{

Thread.sleep(100);

}

catch (InterruptedException e)

{

// TODO Auto-generated catch block

e.printStackTrace();

}

Handler01.post(rSendStr);

}

}

});

write.start();

}

}

catch(Exception e)

{

if(bIfDebug)

{

Log.e(TAG, e.toString());

e.printStackTrace();

}

}

}

}

public Runnable rSendStr = new Runnable(){

public void run()

{

try

{

BufferedWriter bw = new BufferedWriter( new OutputStreamWriter(mSocket01.getOutputStream()) );

strMove = strMoveFlag

+ " " + String.valueOf((int) gyrAngle)

+ " " + String.valueOf( ( ((int)corrected_a) +((accX>3)?90:180) )%360) //由于小车姿态问题,需要进行修正

+ " " + strQR

+" \n";

bw.write(strMove);

bw.flush();

strQR = "0"; // accX>3

}

catch (IOException e)

{

// TODO Auto-generated catch block

e.printStackTrace();

}

}

};

这里用了read write两个thread,分别负责流输入和流输出。这里唯独要提的就是write部分,加上sleep控制流输出频率,不然会造成堵塞。将BufferedWriter通过handler放到Runnable中解决莫名其妙的问题(我的基础不行……惭愧惭愧……)。

PS:用handler解决部分问题,多亏了队友sununs11.这里是我们组项目中截下的代码,会有很多无关于本文双向通信的代码,请无视……后续会放出全部代码与代码解释……这代码是干什么的???请看这个简短视频:基于OpenCV和Android的语音物标识别车

by:season

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android 中使用 Socket 进行网络通信,可以按照以下步骤进行: 1. 在 AndroidManifest.xml 文件中添加网络权限: ```xml <uses-permission android:name="android.permission.INTERNET"/> ``` 2. 在 Android 应用中创建一个 Socket 对象: ```java Socket socket = new Socket(ipAddress, portNumber); ``` 其中 ipAddress 是服务器的 IP 地址,portNumber 是服务器监听的端口号。 3. 获取输入输出流进行数据传输: ```java InputStream input = socket.getInputStream(); OutputStream output = socket.getOutputStream(); ``` 通常情况下,发送数据时需要使用 OutputStream,接收数据时需要使用 InputStream。 4. 发送数据: ```java String message = "Hello, server!"; output.write(message.getBytes()); output.flush(); ``` 这段代码中,message 是要发送的数据,getBytes() 方法将字符串转换为字节数组,write() 方法将字节数组写入输出流中,flush() 方法将缓冲区中的数据刷新到输出流中。 5. 接收数据: ```java byte[] buffer = new byte[1024]; int length = input.read(buffer); String message = new String(buffer, 0, length); ``` 这段代码中,定义了一个大小为 1024 的字节数组 buffer,并通过 read() 方法从输入流中读取数据,length 表示读取到的字节数,最后将字节数组转换为字符串。 6. 关闭 Socket 连接: ```java socket.close(); ``` 在通信结束后,需要关闭 Socket 连接。 以上就是使用 Socket 进行网络通信的基本步骤,需要注意的是,在 Android 应用中不能在主线程中进行网络通信,需要使用异步线程或者线程池进行处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值