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; } //
- 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 = };
- }
- public void SendData(string data)
- {
- try
- {
- if (InOutStream != null && IsRuning && InOutStream.CanWrite)
- {
- var dataBytes = Encoding.Default.GetBytes(data);
- InOutStream.Write(dataBytes, , 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= * ;//30秒读超时
- SetKeepAlive(tcpClient.Client, * , );//无数据传输后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, , cmdBytes.Length);
- #endregion
- Byte[] buffer = new byte[];
- int errCount = ;
- while (Enabled)
- {
- try
- {
- var len = stream.Read(buffer, , buffer.Length);
- var strData = Encoding.Default.GetString(buffer, , len);
- if (len > )
- {
- 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 = ;
- }
- catch (Exception ex)
- {
- errCount++;
- if (errCount == )
- {
- SendData("AT+Beat");
- }
- if (errCount >= )
- {
- throw;
- }
- LogErr(ex);
- Thread.Sleep( * );
- }
- }
- }
- 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[];
- ulong[] numArray = new ulong[];
- if (time == || interval == )
- numArray[] = ;
- else
- numArray[] = ;
- numArray[] = time;
- numArray[] = interval;
- for (int i = ; i < numArray.Length; i++)
- {
- optionInValue[i * + ] = (byte)(numArray[i] >> 0x18 & 0xff);
- optionInValue[i * + ] = (byte)(numArray[i] >> 0x10 & 0xff);
- optionInValue[i * + ] = (byte)(numArray[i] >> & 0xff);
- optionInValue[i * ] = (byte)(numArray[i] & 0xff);
- }
- byte[] bytes = BitConverter.GetBytes();
- socket.IOControl(IOControlCode.KeepAliveValues, optionInValue, bytes);
- }
- catch (Exception exception)
- {
- Console.WriteLine("设置KeepAlive错误:" + exception.Message);
- }
- }
- #endregion
- }
- }
arduino
- #include <SoftwareSerial.h>
- SoftwareSerial mySerial(, ); // RX, TX
- long lastReadTime=;
- long lastWriteTime=;
- int sendCount=;
- String readLine="";
- void setup()
- {
- // Open serial communications and wait for port to open:
- Serial.begin();
- 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();
- 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 >= )
- {
- if(sendCount<=){
- 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 = ;
- mHandler.sendMessage(msg);
- }finally{
- _Stop();
- if(isConnecting){
- _Start();
- }
- }
- }
- private void ConnectAndReceive(String sIP) {
- try
- {
- //连接服务器
- mSocketClient = new Socket(sIP, port); //portnum
- mSocketClient.setSoTimeout( * );
- //取得输入、输出流
- mBufferedReaderClient = new BufferedReader(new InputStreamReader(mSocketClient.getInputStream()));
- mPrintWriterClient = new PrintWriter(mSocketClient.getOutputStream(), true);
- recvMessageClient = "已经连接server!\n";//消息换行
- Message msg = new Message();
- msg.what = ;
- mHandler.sendMessage(msg);
- //break;
- }
- catch (Exception e)
- {
- recvMessageClient = "连接IP异常:" + e.toString() + e.getMessage() + "\n";//消息换行
- Message msg = new Message();
- msg.what = ;
- mHandler.sendMessage(msg);
- throw new RuntimeException("连接IP错误");
- }
- char[] buffer = new char[];
- int count = ;
- int errCount=;
- while (isConnecting)
- {
- try
- {
- //if ( (recvMessageClient = mBufferedReaderClient.readLine()) != null )
- if((count = mBufferedReaderClient.read(buffer))>)
- {
- recvMessageClient = getInfoBuff(buffer, count) + "\n";//消息换行
- Message msg = new Message();
- msg.what = ;
- mHandler.sendMessage(msg);
- errCount=;
- }else {
- throw new RuntimeException("无数据");
- }
- }
- catch (Exception e)
- {
- recvMessageClient = "接收异常:" + e.getMessage() + "\n";//消息换行
- Message msg = new Message();
- msg.what = ;
- mHandler.sendMessage(msg);
- errCount++;
- if(errCount==){
- sendMsg("AT+Beat\r\n");
- }
- if(errCount>=){
- throw new RuntimeException("数据读取错误");
- }
- continue;
- }
- }//end while
- }
- };
- private String getInfoBuff(char[] buff, int count)
- {
- char[] temp = new char[count];
- for(int i=; i<count; i++)
- {
- temp[i] = buff[i];
- }
- return new String(temp);
- }
- }
C#与android连接 SimpleWifi的更多相关文章
- Android 连接 SQL Server (jtds方式)——上
本文将介绍开发Android程序,连接SQL Server,通过第三方包jtds的方式. 如果你有同样的需求,请跟着做一遍,博主将以最详细的方式,进行介绍. 首先说明,Java.Android连接SQ ...
- android连接打印机
android连接 网络打印,主要使用socket连接设备,发送指令给设备. 首先要有设备的IP,端口号一般默认的是9100 //打印设备网络IP etIp.setText("192.16 ...
- Android连接SQLServer详细教程(数据库+服务器+客户端)
摘星 标签: android连接sql http://blog.csdn.net/haoxingfeng/article/details/9111105
- Android 连接网络数据库的方式
以连接MS SQL(sqlserver数据库)的网络数据库为例,从当前搜集的资料来看,一共有两种方式:在Android工程中引入JDBC驱动,直接连接:通过WebService等方法的间接连接. 采用 ...
- Android连接socket服务器上传下载多个文件
android连接socket服务器上传下载多个文件1.socket服务端SocketServer.java public class SocketServer { ;// 端口号,必须与客户端一致 ...
- 阿里云物联网平台: Android 连接阿里云物联网平台
说明 这节是是为下一节做铺垫的 只要是按照我提供的学习路线一节一节的认认真真学过来的,这节就十分的简单 有了前两节的基础,这节呢咱让Android 连接阿里云物联网平台 使用这节的代码 https: ...
- android 连接蓝牙打印机 BluetoothAdapter
android 连接蓝牙打印机 BluetoothAdapter 源码下载地址:https://github.com/yylxy/BluetoothText.git public class Prin ...
- Android连接远程数据库的避坑指南
Android连接远程数据库的避坑指南 今天用Android Studio连接数据库时候,写了个测试连接的按钮,然后连接的时候报错了,报错信息: 2021-09-07 22:45:20.433 705 ...
- Android连接网络打印机进行打印
首先这是网络打印工具类,通过Socket实现,多说一句,网络打印机端口号一般默认的是9100 package com.Ieasy.Tool; import android.annotation.Sup ...
随机推荐
- sql 数据库修复
数据库修复 exec sp_dboption 'dbname1','single user',‘true’ dbcc checkdb('dbname1') dbcc checkdb('dbname1' ...
- canal 监控数据库表 快速使用
https://github.com/alibaba/canal 快速开始 https://github.com/alibaba/canal/wiki/QuickStart 注意 1. vim con ...
- eclipse使用ctrl+shift+F格式化代码失效
通常情况出现这种问题是组合快捷键和别的软件快捷键冲突了, 最常见的是和搜狗输入法冲突, 在设置中找到搜狗输入法然后把冲突的快捷键取消掉就可以了.
- ArcGIS案例学习笔记1_1
ArcGIS案例学习笔记1_1 联系方式:谢老师,135_4855_4328, xiexiaokui#qq.com 时间:第一天上午 准备 0.U盘复制ArcGIS培训*** 1.练习数据不要放到桌面 ...
- sql查询job
use msdb go --if object_id('tempdb..#SqlAgentJob') is not null -- drop table #SqlAgentJob --go decla ...
- 常用的SQL语句(牢记)
上课时的重要内容,其中表 t_hq, t_hq2, 以及字段的名字是举例说明. update t_hq t set t.bumendh = '10086';commit;全表更新电话,commit是提 ...
- A计划(BFS)
A计划 http://acm.hdu.edu.cn/showproblem.php?pid=2102 Time Limit: 3000/1000 MS (Java/Others) Memory ...
- ES5之defineProperty
一 概述 Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象. 对象里目前存在的属性描述符有两种主要形式:数据描述符和存 ...
- UVa 10763 Foreign Exchange(map)
Your non-profitorganization (iCORE - international Confederationof Revolver Enthusiasts) coordinates ...
- 排序矩阵中的从小到大第k个数 · Kth Smallest Number In Sorted Matrix
[抄题]: 在一个排序矩阵中找从小到大的第 k 个整数. 排序矩阵的定义为:每一行递增,每一列也递增. [思维问题]: 不知道应该怎么加,因为不是一维单调的. [一句话思路]: 周围两个数给x或y挪一 ...