遗忘海岸

江湖程序员 -Feiph(LM战士)

导航

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


    }




}
View Code

 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++;
    };
  }
 
}
View Code

 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);
    }
    
}
View Code

 

posted on 2015-03-26 13:35  遗忘海岸  阅读(688)  评论(0编辑  收藏  举报