您的位置:首页 > 理论基础 > 计算机网络

Android Socket和串口编程实践(TCP,UDP,串口集成到一个小项目)

2012-10-14 23:22 579 查看
最近一个项目可能要用到socket和串口方面的编程,网上找了很多这方面的资料,例子,不过都不怎么全,而且很多例子不能直接拿来用。花了几天时间,将TCP、UDP、串口整合到一起做了个小的project,由于没有真机,仅在模拟器上测试通过,且都是在一台机子上,现贴出代码,希望对大家有所帮助。注意涉及IP地址的地方可能需要修改成你自己的地址

一、UDP编程

1 android模拟器端代码

package com.spaceon.udp;

import java.io.IOException;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import com.spaceon.R;

import android.app.Activity;

import android.os.Bundle;

import android.os.Handler;

import android.os.Message;

import android.view.KeyEvent;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

import android.widget.EditText;

import android.widget.TextView;

import android.widget.TextView.OnEditorActionListener;

public class UDPSocketActivity extends Activity {

EditText msg_et = null;

Button send_bt = null;

TextView info_tv = null;

private String msg = null;

private String send_msg = null;

public static Handler mHandler;

public static String content = "";

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.udpsocket);

msg_et = (EditText) findViewById(R.id.msg_et);

send_bt = (Button) findViewById(R.id.send_bt);

info_tv = (TextView) findViewById(R.id.info_tv);

mHandler = new Handler() {

public void handleMessage(Message msg) {

super.handleMessage(msg);

info_tv.setText(content);

}

};

// ExecutorService exec = Executors.newCachedThreadPool();

new Thread() {

@Override

public void run() {

UDPSocketReceive server = new UDPSocketReceive();

server.runReceive();

}

}.start();

// exec.execute(server);

msg_et.setOnEditorActionListener(new OnEditorActionListener() {

public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {

send_msg =v.getText().toString();

return false;

}

});

send_bt.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

new Thread() {

@Override

public void run() {

UDPSocketSend client = new UDPSocketSend(msg_et.getText().toString());

client.send();

}

}.start();

//info_tv.setText(msg);

}

});

}

}

package com.spaceon.udp;

import java.io.IOException;

import java.net.DatagramPacket;

import java.net.DatagramSocket;

import java.net.SocketException;

import com.spaceon.tcp.TCPSocketActivity;

import android.util.Log;

public class UDPSocketReceive {

private static final int RECEIVE_PORT = 6000;

private byte[] msg = new byte[1024];

private boolean life = true;

public UDPSocketReceive() {

}

public boolean isLife() {

return life;

}

public void setLife(boolean life) {

this.life = life;

}

//@Override

public void runReceive() {

DatagramSocket dSocket = null;

byte[] buf=null;

DatagramPacket dPacket = new DatagramPacket(msg, msg.length);

try {

dSocket = new DatagramSocket(RECEIVE_PORT);

while (life) {

try {

dSocket.receive(dPacket);

// Log.i("msg receive", new String(dPacket.getData()));

UDPSocketActivity.content = new String(dPacket.getData()) + "\n";

UDPSocketActivity.mHandler.sendMessage(UDPSocketActivity.mHandler.obtainMessage());

// dPacket.setData(buf);

} catch (IOException e) {

e.printStackTrace();

}

}

} catch (SocketException e) {

e.printStackTrace();

}

// TODO Auto-generated method stub

}

}

package com.spaceon.udp;

import java.io.IOException;

import java.net.DatagramPacket;

import java.net.DatagramSocket;

import java.net.InetAddress;

import java.net.SocketException;

import java.net.UnknownHostException;

import android.os.NetworkOnMainThreadException;

public class UDPSocketSend {

private static final int SEND_PORT = 7000;

private DatagramSocket dSocket = null;

private String msg;

public UDPSocketSend(String msg)

{

super();

this.msg = msg;

}

public void send()

{

StringBuilder sb=new StringBuilder();

InetAddress local = null;

try {

local = InetAddress.getByName("10.0.2.2");

sb.append("已找到服务器,连接中").append("\n");

} catch (UnknownHostException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

catch (NetworkOnMainThreadException e)

{

e.printStackTrace();

}

try {

dSocket = new DatagramSocket();

} catch (SocketException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

sb.append("正在连接服务器").append("\n");

int msgLen=msg==null?0:msg.length();

DatagramPacket dPacket = new DatagramPacket(msg.getBytes(),msgLen,local,SEND_PORT);

try {

dSocket.send(dPacket);

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

sb.append("消息发送成功").append("\n");

dSocket.close();

//return sb.toString();

}

}

2 PC端代码

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

import java.net.DatagramPacket;

import java.net.DatagramSocket;

import java.net.InetAddress;

import java.net.SocketException;

import java.net.UnknownHostException;

public class SocketUDPPC {

private static final int SEND_PORT = 6000;

private static final int RECEIVE_PORT = 7000;

private byte[] msg = new byte[1024];

private boolean life = true;

public SocketUDPPC() {

}

public boolean isLife() {

return life;

}

public void setLife(boolean life) {

this.life = life;

}

public void runReceive() {

DatagramSocket dSocket = null;

byte[] buf = null;

DatagramPacket dPacket = new DatagramPacket(msg, msg.length);

try {

dSocket = new DatagramSocket(RECEIVE_PORT);

while (life) {

try {

dSocket.receive(dPacket);

System.out.println("msg receive "

+ new String(dPacket.getData()).substring(0,

dPacket.getLength()));

// dPacket.setData(buf);

} catch (IOException e) {

e.printStackTrace();

}

}

} catch (SocketException e) {

e.printStackTrace();

}

// TODO Auto-generated method stub

}

public String send(String msg) {

StringBuilder sb = new StringBuilder();

InetAddress local = null;

DatagramSocket dSocket = null;

try {

local = InetAddress.getByName("127.0.0.1");

sb.append("已找到服务器,连接中").append("\n");

} catch (UnknownHostException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

try {

dSocket = new DatagramSocket();

} catch (SocketException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

sb.append("正在连接服务器").append("\n");

int msgLen = msg == null ? 0 : msg.length();

DatagramPacket dPacket = new DatagramPacket(msg.getBytes(), msgLen,

local, SEND_PORT);

try {

dSocket.send(dPacket);

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

sb.append("消息发送成功").append("\n");

dSocket.close();

return sb.toString();

}

public void runSend() {

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

while (true) {

String msg = "";

try {

msg = br.readLine();

// System.out.println("将打开:" + msg);

// //输入完整路径http://www.baidu.com

} catch (IOException e) {

e.printStackTrace();

}

if (msg.equals("exit")) {

System.out.println("退出");

System.exit(-1);

} else {

// SendMsg(HOST,PORT,msg);

System.out.println(send(msg));

System.out.println("将发送:" + msg);

}

}

}

public static void main(String[] args) {

// TODO Auto-generated method stub

// ExecutorService exec = Executors.newCachedThreadPool();

new Thread() {

public void run() {

SocketUDPPC server = new SocketUDPPC();

server.runReceive();

}

}.start();

new Thread() {

public void run() {

SocketUDPPC server = new SocketUDPPC();

server.runSend();

}

}.start();

// exec.execute(server);

}

}

注意:由于PC机不能直接向模拟器发送数据,因此要进行端口重定向:在命令终端输入 telnet 127.0.0.1 5554登陆模拟器,再输入redir add udp:6000:6000。模拟器和PC端都使用两个端口,一个端口收,一个端口发,从而实现模拟器和PC机都能够进行收发(网上很多都区分服务器和客户端,这里没有区分,要仅限一方只进行收获发时只要去掉一些代码即可)

二、TCP编程

1 android模拟器端代码

package com.spaceon.tcp;

import java.io.DataOutputStream;

import java.io.IOException;

import java.io.OutputStream;

import java.net.Socket;

import java.net.UnknownHostException;

import com.spaceon.R;

import com.spaceon.udp.UDPSocketSend;

import com.spaceon.udp.UDPSocketReceive;

import android.app.Activity;

import android.os.Bundle;

import android.os.Handler;

import android.os.Message;

import android.os.NetworkOnMainThreadException;

import android.util.Log;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

import android.widget.EditText;

import android.widget.TextView;

public class TCPSocketActivity extends Activity {

Button send_bt = null;

public static Handler mHandler;

private TextView textView;

public static String content = "";

EditText msg_et = null;

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.tcpsocket);

send_bt = (Button) findViewById(R.id.sendButton);

textView = (TextView)findViewById(R.id.outputId);

msg_et = (EditText)findViewById(R.id.inputId);

mHandler = new Handler() {

public void handleMessage(Message msg) {

super.handleMessage(msg);

textView.setText(content);

}

};

new Thread() {

@Override

public void run() {

TCPSocketReceive receiveSocket = new TCPSocketReceive();

receiveSocket.receive();

}

}.start();

send_bt.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

new Thread() {

@Override

public void run() {

TCPSocketSend tCPSocketSend = new TCPSocketSend(msg_et.getText().toString());

tCPSocketSend.send();

}

}.start();

//info_tv.setText(msg);

}

});

}

}

package com.spaceon.tcp;

import java.io.BufferedReader;

import java.io.InputStreamReader;

import java.net.ServerSocket;

import java.net.Socket;

import android.app.Activity;

import android.content.Intent;

import android.net.Uri;

import android.os.Bundle;

import android.os.Handler;

import android.os.Message;

import android.util.Log;

import android.widget.TextView;

public class TCPSocketReceive {

/** Called when the activity is first created. */

private final int SERVER_PORT = 8090;

public void receive() {

try {

// ServerSocket serverSocket = new ServerSocket(SERVER_PORT);

ServerSocket serverSocket = new ServerSocket(SERVER_PORT);

//
循环侦听客户端连接请求

Log.d("test", "startServer:");

while (true) {

Socket client = serverSocket.accept();

try {

Log.d("test", "有人来访:");

//
等待客户端发送打开网站的消息

BufferedReader in = new BufferedReader(

new InputStreamReader(client.getInputStream()));

String str = in.readLine();

TCPSocketActivity.content = str + "\n";

TCPSocketActivity.mHandler.sendMessage(TCPSocketActivity.mHandler.obtainMessage());

} catch (Exception e) {

e.printStackTrace();

} finally {

client.close();

}

Thread.sleep(1000);

}

} catch (Exception e) {

Log.d("test", "Exception:");

e.printStackTrace();

}

}

}

package com.spaceon.tcp;

import java.io.DataOutputStream;

import java.io.IOException;

import java.io.OutputStream;

import java.net.Socket;

import java.net.UnknownHostException;

import android.app.Activity;

import android.os.Bundle;

import android.util.Log;

import android.view.View;

import android.os.NetworkOnMainThreadException;

public class TCPSocketSend {

private final int SERVER_PORT = 51706;

private final String SERVER_IP = "192.168.40.29";

private String content = "";

/** Called when the activity is first created. */

private String msg;

public TCPSocketSend(String msg) {

this.msg = msg;

}

public void send() {

Socket socket;

try {

socket = new Socket(SERVER_IP, SERVER_PORT);

OutputStream ops = socket.getOutputStream();

DataOutputStream dos = new DataOutputStream(ops);

dos.write(msg.getBytes());

Log.d("test", "send succ");

dos.close();

} catch (UnknownHostException e) {

Log.d("test", "UnknownHostException");

// TODO Auto-generated catch block

e.printStackTrace();

} catch (NetworkOnMainThreadException e) {

Log.d("test", "NetworkOnMainThreadException");

} catch (IOException e) {

Log.d("test", "IOException");

// TODO Auto-generated catch block

e.printStackTrace();

} finally {

Log.d("test", "finally");

}

}

}

2 PC端代码

import java.io.BufferedReader;

import java.io.BufferedWriter;

import java.io.IOException;

import java.io.InputStreamReader;

import java.io.OutputStreamWriter;

import java.io.PrintWriter;

import java.net.ServerSocket;

import java.net.Socket;

public class SocketTCPPC {

public static final int SERVERPORT = 51706;

public static final String adb_path = "C:\\sdk\\platform-tools\\adb ";// adb所在路径

private final String HOST = "127.0.0.1";

private final int PORT = 8080;

private static Socket socket = null;

private static BufferedReader in = null;

private static PrintWriter out = null;

public void runReceive() {

try {

System.out.println("S: Connecting...");

ServerSocket serverSocket = new ServerSocket(SERVERPORT);

while (true) {

Socket client = serverSocket.accept();

System.out.println("S: Receiving...");

try {

BufferedReader in = new BufferedReader(

new InputStreamReader(client.getInputStream()));

String str = in.readLine();

System.out.println("S: Received: '" + str + "'");

} catch (Exception e) {

System.out.println("S: Error");

e.printStackTrace();

} finally {

client.close();

System.out.println("S: Done.");

}

}

} catch (Exception e) {

System.out.println("S: Error");

e.printStackTrace();

}

}

public void SendMsg(String host, int port, String msg) {

try {

socket = new Socket(host, port);

in = new BufferedReader(new InputStreamReader(

socket.getInputStream()));

out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(

socket.getOutputStream())), true);

if (socket.isConnected()) {

if (!socket.isOutputShutdown()) {

out.println(msg);

out.flush();

out.close();

in.close();

socket.close();

System.out.println("将打开:" + msg);

}

}

} catch (IOException ex) {

ex.printStackTrace();

System.out.println("login exception" + ex.getMessage());

}

}

public void runSend() {

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

while (true) {

String msg = "";

try {

msg = br.readLine();

// System.out.println("将打开:" + msg);

// //输入完整路径http://www.baidu.com

} catch (IOException e) {

e.printStackTrace();

}

if (msg.equals("exit")) {

System.out.println("退出");

System.exit(-1);

} else {

SendMsg(HOST, PORT, msg);

}

}

}

public static void main(String a[]) {

try {

//
把虚拟机的8090端口绑定到PC本机的8080端口,这样当PC向8080发送数据时实际上是发到虚拟机的8090端口

// Runtime.getRuntime().exec(G3ExpPCclient.adb_path +

// "
–s emulator-5554 forward tcp:8080 tcp:8090");这个方法不好用

Runtime.getRuntime().exec(

SocketTCPPC.adb_path + " forward tcp:8080 tcp:8090");//
这个好用

System.out.println("已经将虚拟机端口8090绑定到PC端口8080 " + adb_path);

} catch (IOException e1) {

e1.printStackTrace();

}

new Thread() {

public void run() {

new SocketTCPPC().runReceive();

}

}.start();

new Thread() {

public void run() {

new SocketTCPPC().runSend();

}

}.start();

}

}

三串口编程

操作串口时必须要有对串口文件读写权限,所以要以超级用户身份修改,即登陆模拟器后执行chmod 777 +(串口文件路径),也可以在代码中执行这个操作。在模拟器上貌似不用这个步骤,但真机上必须有,原因可能是很多真机没有被root,模拟器是root了的。

测试时可以先创建两个虚拟串口2,3,在命令行输入emulator @yourAVD –qemu –serial COM2

,启动进入模拟器后,在模拟器串口设置界面,选择ttyS2(应该这个就对应串口2),再打开串口助手,就可以相互收发了。

也可以另外再创建一个AVD模拟器虚拟机,在命令行输入emulator @yourAVD –qemu –serial COM3,实现两个模拟器之间的相互通信

串口的代码就是直接下载的串口API带的代码,太多就不贴了

AndroidManifest..xml文件

<?xml
version="1.0"
encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.spaceon"
android:versionCode="1"
android:versionName="1.0"
>

<uses-sdk
android:minSdkVersion="15"
/>
<uses-permission
android:name="android.permission.INTERNET"/>
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"

android:name="Application">
<activity
android:name=".socketAndSerialPortDemoActivity"
android:label="@string/app_name"
>
<intent-filter>
<action
android:name="android.intent.action.MAIN"
/>

<category
android:name="android.intent.category.LAUNCHER"
/>
</intent-filter>
</activity>

<activity android:name="com.spaceon.udp.UDPSocketActivity"
>
</activity>
<activity
android:name="com.spaceon.tcp.TCPSocketActivity">
</activity>
<activity
android:name="com.spaceon.serialPort.MainMenu">
</activity>
<activity
android:name="com.spaceon.serialPort.SerialPortPreferences"
>
</activity>
<activity
android:name="com.spaceon.serialPort.ConsoleActivity"
>
</activity>
<activity
android:name="com.spaceon.serialPort.LoopbackActivity"
>
</activity>
<activity
android:name="com.spaceon.serialPort.Sending01010101Activity"></activity>
</application>

</manifest>

Main.xml文件

<?xml
version="1.0"
encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal"
>

<!--
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello" />
-->
<Button
android:id="@+id/tcp_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TCP"
/>

<Button
android:id="@+id/udp_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="UDP"
/>

<Button
android:id="@+id/serial_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="串口"
/>

</LinearLayout>

tcpsocket.xml文件

<?xml
version="1.0"
encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
>

<EditText
android:id="@+id/inputId"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>

<requestFocus
/>
</EditText>

<Button
android:id="@+id/sendButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="send"
/>

<TextView
android:id="@+id/outputId"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>

</LinearLayout>

Udpsocket.xml文件

<?xml
version="1.0"
encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
>

<EditText
android:id="@+id/msg_et"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>

<requestFocus
/>
</EditText>
<Button
android:id="@+id/send_bt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Send"
/>
<TextView
android:id="@+id/info_tv"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
</LinearLayout>

工程目录结构如下:

完整代码不知道怎么黏贴到博客里,有需要的联系我 QQ 271055031
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: