有时候 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的更多相关文章

  1. Android 连接 SQL Server (jtds方式)——上

    本文将介绍开发Android程序,连接SQL Server,通过第三方包jtds的方式. 如果你有同样的需求,请跟着做一遍,博主将以最详细的方式,进行介绍. 首先说明,Java.Android连接SQ ...

  2. android连接打印机

    android连接  网络打印,主要使用socket连接设备,发送指令给设备. 首先要有设备的IP,端口号一般默认的是9100 //打印设备网络IP etIp.setText("192.16 ...

  3. Android连接SQLServer详细教程(数据库+服务器+客户端)

    摘星 标签: android连接sql http://blog.csdn.net/haoxingfeng/article/details/9111105

  4. Android 连接网络数据库的方式

    以连接MS SQL(sqlserver数据库)的网络数据库为例,从当前搜集的资料来看,一共有两种方式:在Android工程中引入JDBC驱动,直接连接:通过WebService等方法的间接连接. 采用 ...

  5. Android连接socket服务器上传下载多个文件

    android连接socket服务器上传下载多个文件1.socket服务端SocketServer.java public class SocketServer { ;// 端口号,必须与客户端一致 ...

  6. 阿里云物联网平台: Android 连接阿里云物联网平台

    说明 这节是是为下一节做铺垫的 只要是按照我提供的学习路线一节一节的认认真真学过来的,这节就十分的简单 有了前两节的基础,这节呢咱让Android 连接阿里云物联网平台 使用这节的代码  https: ...

  7. android 连接蓝牙打印机 BluetoothAdapter

    android 连接蓝牙打印机 BluetoothAdapter 源码下载地址:https://github.com/yylxy/BluetoothText.git public class Prin ...

  8. Android连接远程数据库的避坑指南

    Android连接远程数据库的避坑指南 今天用Android Studio连接数据库时候,写了个测试连接的按钮,然后连接的时候报错了,报错信息: 2021-09-07 22:45:20.433 705 ...

  9. Android连接网络打印机进行打印

    首先这是网络打印工具类,通过Socket实现,多说一句,网络打印机端口号一般默认的是9100 package com.Ieasy.Tool; import android.annotation.Sup ...

随机推荐

  1. WDA-WebDynpro Demo & FPM Demo

    Web Dynpro Demo package: SWDP_DEMO SWDP_TEST   FPM Demo package: APB_FPM_DEMO APB_FPM_DEMO_SCENARIO

  2. UI5-文档-4.17-Fragment Callbacks

    现在我们已经集成了对话框,是时候添加一些用户交互了.用户肯定希望在某个时候再次关闭对话框,因此我们添加一个按钮来关闭对话框并分配一个事件处理程序. Preview The dialog now has ...

  3. centoros 环境安装

    1. nginx rpm -ivh http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.no ...

  4. cmake编译参数

    进入源码目录后 cmake . -LH  --查看之前编译参数 ccmake .  使用cmake gui界面进行查看和编辑编译用到的参数 (推荐) 源码目录下 INSTALL-SOURCE 文件后面 ...

  5. 浅谈Spark应用程序的性能调优

    浅谈Spark应用程序的性能调优 :http://geek.csdn.net/news/detail/51819 下面列出的这些API会导致Shuffle操作,是数据倾斜可能发生的关键点所在 1. g ...

  6. jquery parents用法

    之前一直用find 现在用parents var w = $("div"); w = $("div").parents('.class'); //在Parent ...

  7. maven 项目 编码

    今天在DOS下执行mvn compile命令时报错说缺少必要符号,事实上根本就没有缺少,但何以如此呢,为啥eclipse在编译时就没有这问题呢? 原因是编码的问题造成的! eclipse在编译的使用使 ...

  8. linux的文件类型和权限

    Linux下使用ll或ls -l查看文件的信息 (ll和ls-l的区别:ll会显示出当前目录下的隐藏文件,而ls -l不会)   文件信息分为:文件类型.权限.链接数.所属用户.所属用户组.文件大小. ...

  9. Codeforces Round #533 (Div. 2)

    C: 题意: 有n个整数ai,数列a有两个神奇的性质.1.所有的整数都在[l,r]范围内.2.这n个数的和能被3整除.现在给出l和r,和个数n,问你有多少种方法构造出数列a,方案数mod1e9+7. ...

  10. MyBatis高级查询

    -------------------------siwuxie095 MyBatis 高级查询 1.MyBatis 作为一个 ORM 框架,也对 SQL 的高级查询做了支持, MyBatis 高级查 ...