Este artículo explica principalmente la implementación del cliente de comunicación de Android TCP Socket (Cliente) y el servidor (Servidor) Demostración (con código fuente), preste atención al método readLine () de BufferedReader [((line = br.readLine ())! = null)] El problema de bloqueo y el procesamiento de conversión de los datos del proyecto del hardware de acoplamiento en el hexadecimal && byte && int.
Tai Hang
Recientemente, hubo un proyecto que necesitaba usar la comunicación TCP Socket y se encontró con un gran pozo, así que hice esta demostración.
Al leer el flujo de entrada del socket, muchos códigos se escribirán de esta manera, y generalmente no hay problema, pero el método readLine () se bloqueará cuando no pueda leer el avance de línea y el retorno de carro.
String line = null;
while ((line = br.readLine ())! = Null ) {
}
readLine () es una función de bloqueo, puede hacer clic para ver el código fuente, solo cuando encuentre un salto de línea o un retorno de carro (' \ n ',' \ r 'correspondiente a hexadecimal es 0D 0A) regresará, y algunos módulos le devolverán datos sin estos dos terminadores, por lo que causa bloqueo y el programa no puede continuar. En este caso, si el lado del módulo está dispuesto a modificar y agregar un terminador, no hay problema. Si no es conveniente cambiar el módulo, este método no se puede utilizar y se debe cambiar el método de escritura.
Herramientas de depuración
Para la depuración en tiempo real, podemos usar algunas herramientas del lado de la PC, como asistentes de depuración de TCP y herramientas de prueba de TCP. Hay muchos usuarios y la operación también es tonta. Complete la IP y el puerto y luego establezca o conecte .
Demostración e implementación de demostración
Deje de decir tonterías, vaya directamente al tema de hoy, ¡echemos un vistazo a cómo usar el protocolo TCP / IP en Android para comunicarse con el servidor usando Socket!
1. Permiso
<uses-permission android:name="android.permission.INTERNET"/>
En segundo lugar, la implementación del servidor, en términos simples, toma 3 pasos
1. Cree un ServerSocket, monitoree el puerto y espere a que el Socket del cliente se conecte
2. Obtenga el mensaje del cliente desde el Socket
3. Envíe un mensaje al cliente a través del Socket.
El código central es el siguiente
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 InputStreamReader(mSocket.getInputStream(),"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 {
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(mSocket.getOutputStream())), true);
out.println(mServerSendMessage);
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
Tres, implementación del lado del cliente, similar al proceso del lado del servidor
1. Establecer una conexión de socket con el servidor
2. Obtener flujos de entrada y salida
3. Recibir / enviar mensajes
//与服务器建立连接
Socket mClientSocket = new Socket(mClientIp, mClientPort);
//从socket获取输入输出流
BufferedReader mClientIn = new BufferedReader(new InputStreamReader(mClientSocket.getInputStream()));
PrintWriter mClientOut = new PrintWriter(new BufferedWriter(new OutputStreamWriter(mClientSocket.getOutputStream())), true);
//监听服务端下发的消息
String clientReceiverMessage;
if ((clientReceiverMessage = mClientIn.readLine()) != null) {
if (mOnConnectListener != null) {
mOnConnectListener.onMessage(clientReceiverMessage);
}
}
//给服务端发消息
mClientOut.println(mClientSendMessage);
Interfaz de escucha de paquete de código
En el proceso de desarrollo real, generalmente encapsulamos el Socket y luego configuramos la interfaz Listener externamente, manejamos la lógica comercial en otros módulos y algunos necesitan manejar múltiples conexiones y comunicaciones de socket.
Ejemplo de implementación de código del lado del servidor
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;
}
………………………………
………………………………
………………………………
}
Procesamiento de envío y recepción hexadecimal
El protocolo de comunicación del proyecto de hardware de acoplamiento puede usar hexadecimal, por lo que los datos deben convertirse en la cadena \ byte \ int hexadecimal, pero la esencia de la parte de comunicación es la misma, el código es el siguiente
//十六进制 发送
try {
//byte[] msg = {(byte) 0xaa,(byte) 0xbb,(byte) 0x0d,(byte) 0x0a};
byte[] msg = IntByteStringHexUtil.hexStrToByteArray("AABB0D0A");
OutputStream socketWriter = socket.getOutputStream();
socketWriter.write(msg);
} catch (IOException e) {
e.printStackTrace();
}
//十六进制 接收
InputStream socketReader = socket.getInputStream();
byte buf[] = new byte[1024];
int len = socketReader.read(buf);
byte data[] = new byte[len];
System.arraycopy(buf, 0, data, 0, len);
logClient(len+","+IntByteStringHexUtil.byteArrayToHexStr(data));
Dirección de descarga de la fuente de demostración
El código fuente también se coloca en CSDN, puede aprender de él si lo necesita
===> Ejemplo de comunicación de Android TCP Socket Código fuente de demostración Descarga de Apk