C#与android连接 SimpleWifi
有时候 Read时会返回0长度
-----
当连续2次每读到数据时,建议发个心跳信息,然后单片机给个回复
C#
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Net.Sockets; using System.Diagnostics; namespace SimpleWiFITest { public class SimpleWifiTCPClient : IDisposable { public String IP { get; private set; } public int Port { get; private set; } //7788 public bool IsRuning{get; private set;} private bool Enabled = false; private bool disposed = false; private NetworkStream InOutStream = null; public GatherDataInfo LastGatherData { get; private set; } public SimpleWifiTCPClient(string ip, int port) { this.IP = ip; this.Port = port; IsRuning = false; LastGatherData = new GatherDataInfo() { Status = 0 }; } public void SendData(string data) { try { if (InOutStream != null && IsRuning && InOutStream.CanWrite) { var dataBytes = Encoding.Default.GetBytes(data); InOutStream.Write(dataBytes, 0, dataBytes.Length); } } catch { } } public void Start() { if (IsRuning) return; Enabled = true; IsRuning = true; ThreadPool.QueueUserWorkItem((o) => { _Start(); }); } private void _Start() { LogInfo("进入工作线程:" + Thread.CurrentThread.ManagedThreadId); using (TcpClient tcpClient = new TcpClient()) { NetworkStream stream = null; try { tcpClient.Connect(IP, Port); tcpClient.ReceiveTimeout= 1000 * 30;//30秒读超时 SetKeepAlive(tcpClient.Client, 1000 * 30, 1000);//无数据传输后30秒发起心跳检测,每1秒进行一次,5次失败后streamRead将报错 stream = tcpClient.GetStream(); InOutStream = stream; #region 发送指令 让电子秤每秒发送一次 var cmd = "CP\r\n1P\r\n"; var cmdBytes = Encoding.Default.GetBytes(cmd); stream.Write(cmdBytes, 0, cmdBytes.Length); #endregion Byte[] buffer = new byte[1024]; int errCount = 0; while (Enabled) { try { var len = stream.Read(buffer, 0, buffer.Length); var strData = Encoding.Default.GetString(buffer, 0, len); if (len > 0) { LogInfo("Data:" + strData.TrimEnd("\r\n".ToCharArray()) + " Len:" + len); } else { throw new Exception("无数据!"); } #region 解析数据 //if (len == 17) //{ //var v = strData.Substring(0, 1).Trim() + strData.Substring(1, 7).Trim(); //var legend = strData.Substring(14, 3); //将数据入队列 //var data = new GatherDataInfo() { Status = 1, AddTime = DateTime.Now, RawStr = BitConverter.ToString(buffer, 0, len), StrValue = v, Legend = legend }; //} #endregion errCount = 0; } catch (Exception ex) { errCount++; if (errCount == 2) { SendData("AT+Beat"); } if (errCount >= 3) { throw; } LogErr(ex); Thread.Sleep(1000 * 3); } } } catch (Exception ex) { LogErr(ex); } finally { try { stream.Close(); } catch { } try { tcpClient.Close(); } catch { } IsRuning = false; if (Enabled) { IsRuning = true; ThreadPool.QueueUserWorkItem((o) => { _Start(); }); } LogInfo("退出工作线程:" + Thread.CurrentThread.ManagedThreadId); } } } private void LogErr(Exception ex) { Console.WriteLine(ex.Message); } private void LogInfo(string msg) { Console.WriteLine(msg); } public void Stop() { Enabled = false; } #region IDisposable Members /// <summary> /// Performs application-defined tasks associated with freeing, /// releasing, or resetting unmanaged resources. /// </summary> public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } /// <summary> /// Releases unmanaged and - optionally - managed resources /// </summary> /// <param name="disposing"><c>true</c> to release both managed /// and unmanaged resources; <c>false</c> /// to release only unmanaged resources. /// </param> protected virtual void Dispose(bool disposing) { if (!this.disposed) { if (disposing) { try { Stop(); } catch { } } disposed = true; } } #endregion #region Help Method /// <summary> /// 毫秒为单位 /// </summary> /// <param name="socket"></param> /// <param name="time"></param> /// <param name="interval"></param> private void SetKeepAlive(Socket socket, ulong time, ulong interval) { try { byte[] optionInValue = new byte[12]; ulong[] numArray = new ulong[3]; if (time == 0 || interval == 0) numArray[0] = 0; else numArray[0] = 1; numArray[1] = time; numArray[2] = interval; for (int i = 0; i < numArray.Length; i++) { optionInValue[i * 4 + 3] = (byte)(numArray[i] >> 0x18 & 0xff); optionInValue[i * 4 + 2] = (byte)(numArray[i] >> 0x10 & 0xff); optionInValue[i * 4 + 1] = (byte)(numArray[i] >> 8 & 0xff); optionInValue[i * 4] = (byte)(numArray[i] & 0xff); } byte[] bytes = BitConverter.GetBytes(0); socket.IOControl(IOControlCode.KeepAliveValues, optionInValue, bytes); } catch (Exception exception) { Console.WriteLine("设置KeepAlive错误:" + exception.Message); } } #endregion } }
arduino
#include <SoftwareSerial.h> SoftwareSerial mySerial(7, 8); // RX, TX long lastReadTime=0; long lastWriteTime=0; int sendCount=0; String readLine=""; void setup() { // Open serial communications and wait for port to open: Serial.begin(9600); while (!Serial) { ; // wait for serial port to connect. Needed for Leonardo only } Serial.println("Goodnight moon!"); // set the data rate for the SoftwareSerial port mySerial.begin(9600); mySerial.println("Hello, world?"); } void loop() // run over and over { while(mySerial.available()){ lastReadTime=millis(); char c=mySerial.read(); readLine +=c; if(readLine.startsWith("AT+Beat\r\n")) { mySerial.println("OK!"); } Serial.write(c); if(c=='\n'){ readLine=""; } } if(millis()- lastWriteTime >= 1000) { if(sendCount<=60){ lastWriteTime=millis(); mySerial.println(String( millis())); sendCount++; }; } }
android
package cn.fstudio.net; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket; import junit.framework.Protectable; import android.R.integer; import android.content.Context; import android.os.Handler; import android.os.Message; import android.util.Log; import android.widget.Toast; public class TCPClient { private Handler mHandler=null; private boolean isConnecting = false; private Thread mThreadClient = null; private Socket mSocketClient = null; static BufferedReader mBufferedReaderClient = null; static PrintWriter mPrintWriterClient = null; private String recvMessageClient = ""; private String ip; private int port; public boolean isConnecting() { return isConnecting; } public String getRecvMessageClient() { return recvMessageClient; } public TCPClient(Handler handler,String ip,int port) { this.mHandler=handler; this.ip=ip; this.port=port; } public void turnOffON() { if (isConnecting) { isConnecting = false; _Stop(); } else { isConnecting = true; _Start(); } } private void _Start(){ mThreadClient = new Thread(mRunnable); mThreadClient.start(); } private void _Stop(){ try { if(mSocketClient!=null) { mSocketClient.close(); mSocketClient = null; mPrintWriterClient.close(); mPrintWriterClient = null; mBufferedReaderClient.close(); mBufferedReaderClient=null; } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } mThreadClient.interrupt(); } public void sendMsg(Context mContext, String msg){ try { mPrintWriterClient.println(msg);//发送给服务器 mPrintWriterClient.flush(); } catch (Exception e) { // TODO: handle exception Toast.makeText(mContext, "发送异常:" + e.getMessage(), Toast.LENGTH_SHORT).show(); } } public void sendMsg(String msg){ try { mPrintWriterClient.println(msg);//发送给服务器 mPrintWriterClient.flush(); } catch(Exception e) { } } //线程:监听服务器发来的消息 private Runnable mRunnable = new Runnable() { public void run() { String sIP = ip; Log.d("gjz", "IP:"+ sIP + ":" + port); try{ ConnectAndReceive(sIP); //连接并循环接收数据 }catch(Exception e){ recvMessageClient = "接收异常:" + e.getMessage() + "\n";//消息换行 Message msg = new Message(); msg.what = 1; mHandler.sendMessage(msg); }finally{ _Stop(); if(isConnecting){ _Start(); } } } private void ConnectAndReceive(String sIP) { try { //连接服务器 mSocketClient = new Socket(sIP, port); //portnum mSocketClient.setSoTimeout(1000 * 30); //取得输入、输出流 mBufferedReaderClient = new BufferedReader(new InputStreamReader(mSocketClient.getInputStream())); mPrintWriterClient = new PrintWriter(mSocketClient.getOutputStream(), true); recvMessageClient = "已经连接server!\n";//消息换行 Message msg = new Message(); msg.what = 1; mHandler.sendMessage(msg); //break; } catch (Exception e) { recvMessageClient = "连接IP异常:" + e.toString() + e.getMessage() + "\n";//消息换行 Message msg = new Message(); msg.what = 1; mHandler.sendMessage(msg); throw new RuntimeException("连接IP错误"); } char[] buffer = new char[256]; int count = 0; int errCount=0; while (isConnecting) { try { //if ( (recvMessageClient = mBufferedReaderClient.readLine()) != null ) if((count = mBufferedReaderClient.read(buffer))>0) { recvMessageClient = getInfoBuff(buffer, count) + "\n";//消息换行 Message msg = new Message(); msg.what = 1; mHandler.sendMessage(msg); errCount=0; }else { throw new RuntimeException("无数据"); } } catch (Exception e) { recvMessageClient = "接收异常:" + e.getMessage() + "\n";//消息换行 Message msg = new Message(); msg.what = 1; mHandler.sendMessage(msg); errCount++; if(errCount==2){ sendMsg("AT+Beat\r\n"); } if(errCount>=3){ throw new RuntimeException("数据读取错误"); } continue; } }//end while } }; private String getInfoBuff(char[] buff, int count) { char[] temp = new char[count]; for(int i=0; i<count; i++) { temp[i] = buff[i]; } return new String(temp); } }