Android安卓TCPSocket通信实现Demo(附Apk源码)
本⽂主要讲解安卓(Android)TCP Socket通讯客户端(Client)和服务器(Server)Demo的实现(附源码),要注意BufferedReader的readLine()⽅法【((line = br.readLine()) != null)】的阻塞问题,以及对接硬件的项⽬数据在⼗六进制&&byte&&int的转换处理。
⽬录
⼤坑
最近有个项⽬需要⽤到TCP Socket通讯,遇到了⼀个⼤坑,所以做了这个Demo。
读取socket输⼊流的时候很多代码都会这么写,⼀般也不会有什么问题,但是readLine()⽅法读取不到换⾏和回车时会阻塞!
String line = null;
while ((line = br.readLine()) != null) {
}
readLine()是个阻塞函数,可以点进去查看源码,只有遇到换⾏或者回车回车符(’\n’,’\r’ 对应⼗六进制是 0D 0A)才会返回,⽽有些模块返回给你的数据不带这两个结束符,所以导致阻塞,程序不能⾛下去。这种情况⼀般如果模块那边愿意修改加上结束符,那就没问题。如果模块那边⼜不⽅便改,那就不能⽤这种⽅式了,得换种写法。
调试⼯具
调试的实时我们可以借助⼀些PC端的⼯具,TCP调试助⼿、TCP测试⼯具类似的,度娘下很多,操作也是傻⽠式的,填写IP和端⼝然后建⽴或者连接。
Demo演⽰及实现
废话少说,直接进⼊今天的主题,下⾯就看看如何在Android上利⽤TCP/IP协议使⽤Socket与Server进⾏通讯吧!⼀、权限
<uses-permission android:name="android.permission.INTERNET"/>
⼆、服务端实现,简单来说就3步
1、创建ServerSocket ,监听端⼝,等待客户端Socket连接
2、从Socket⾥获取的客户端发来的消息
3、通过Socket给客户端发消息
核⼼代码如下
class ServerSocketThread extends Thread {
@Override
public void run() {
try {
// 创建ServerSocket
ServerSocket serverSocket = new ServerSocket(9999);
System.out.println("--开启服务器,监听端⼝ 9999--");
// 监听端⼝,等待客户端连接
while (true) {
System.out.println("--等待客户端连接--");
Socket socket = serverSocket.accept(); //等待客户端连接
System.out.println("得到客户端连接:" + socket);
startReader(socket);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 从参数的Socket⾥获取消息
*/
private static void startReader(final Socket mSocket) {
new Thread(){
@Override
public void run() {
try {
// 获取读取流
BufferedReader in = new BufferedReader(new InputStream(),"utf-8"))
String line="";
while ((line = in.readLine()) != null) {// 读取数据
System.out.println("*等待客户端输⼊*");
System.out.println("获取到客户端的信息:" + line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
//通过socket来给客户端发送消息
private void serverSendMessage(String mServerSendMessage) {
new Thread() {
@Override
public void run() {
PrintWriter out;
try {
socket通信在哪一层out = new PrintWriter(new BufferedWriter(new OutputStream())), true);
out.println(mServerSendMessage);
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
三、客户端实现,跟服务器端流程类似
1、与服务器建⽴Socket连接
2、获取到输⼊输出流
3、收/发送消息
//与服务器建⽴连接
Socket mClientSocket = new Socket(mClientIp, mClientPort);
//从socket获取输⼊输出流
BufferedReader mClientIn = new BufferedReader(new InputStream()));
PrintWriter mClientOut = new PrintWriter(new BufferedWriter(new OutputStream())), true);
//监听服务端下发的消息
String clientReceiverMessage;
if ((clientReceiverMessage = adLine()) != null) {
if (mOnConnectListener != null) {
}
}
//给服务端发消息
mClientOut.println(mClientSendMessage);
代码封装Listener接⼝
在实际开发过程中,我们⼀般会把Socket这块封装起来,然后对外设置Listener接⼝,在其它模块⾥处理业务逻辑,也有的需要处理多个socket 连接和通讯,
服务器端代码实现⽰例
public class TcpServer {
private static final String TAG = "TcpServer";
private static TcpServer mTcpServer = new TcpServer();
private OnListener mOnListener;
private ServerSocketThread mServerSocketThread;
public static TcpServer getInstance() {
return mTcpServer;
}
public void setOnListener(OnListener onListener) {
mOnListener = onListener;
}
public interface OnListener {
void onStart();
void onNewClient(String serverIp, String clientIp, int count);
void onError(Throwable e, String message);
void onMessage(String ip, String message);
void onAutoReplyMessage(String ip, String message);
void onClientDisConnect(String ip);
void onConnectTimeOut(String ip);
}
public void setPort(int port) {
mServerPort = port;
}
………………………………
………………………………
…
……………………………
}
⼗六进制收发处理
对接硬件的项⽬通讯协议有可能是⽤⼗六进制的,所以数据要在字符串\byte\int ⼗六进制转换,不过通讯部分本质⼀样,代码如下 //⼗六进制发送
try {
//byte[] msg = {(byte) 0xaa,(byte) 0xbb,(byte) 0x0d,(byte) 0x0a};
byte[] msg = IntByteStringHexUtil.hexStrToByteArray("AABB0D0A");
OutputStream socketWriter = OutputStream();
socketWriter.write(msg);
} catch (IOException e) {
e.printStackTrace();
}
//⼗六进制接收
InputStream socketReader = InputStream();
byte buf[] = new byte[1024];
int len = ad(buf);
byte data[] = new byte[len];
System.arraycopy(buf, 0, data, 0, len);
logClient(len+","+IntByteStringHexUtil.byteArrayToHexStr(data));
Demo源码下载地址
源码也都放在CSDN上了,有需要的可以借鉴
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论