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 ...
随机推荐
- as3 加载gif loader
as3原生不支持gif动态图 loader 加载gif ,内容只是以bitmap加载进来 需要动态,另外衍生类: https://files.cnblogs.com/files/dt1991/GifL ...
- 多线程--Java
多线程: 1.进程和线程 进程是资源分配的最小单位,线程是CPU调度的最小单位. 每个进程的创建都需要系统为其开辟资源内存空间,并发执行的程序在执行过程中分配和管理资源的基本单位,速度和销毁也较慢.进 ...
- Haskell语言学习笔记(59)Bitraversable
Bitraversable class (Bifunctor t, Bifoldable t) => Bitraversable t where bitraverse :: Applicativ ...
- java基础五 [数字与静态](阅读Head First Java记录)
本章主要讲了静态变量.静态方法,final关键词.以及介绍了怎么对数字和日期进行格式化输出.这里对这些内容进行了整理.本章还介绍了java.util.Date和java.util.Calendar来操 ...
- js获取地址栏信息
参考: http://www.w3school.com.cn/jsref/dom_obj_location.asp http://www.xxx.com:8081/ location.host = w ...
- java学习笔记----@Override的作用
初学java或多或少都会有这样的疑问,@Override有什么用,有的时候写,有的时候又不写,搞的初学者甚是郁闷. 做了一两年的开发说起这个问题不一定能够对答如流.小弟才疏学浅,花了点时间,看了一下资 ...
- android笔记 : Content provider内容提供器
内容提供器(Content Provider)主要用于在不同的应用程序之间实现数据共享的功能. 内容提供器的用法一般有两种,一种是使用现有的内容提供器来读取和操作相应程序中的数据,另一种是创建自己的内 ...
- Cannot resolve class or package 'dbcp' Cannot resolve class 'BasicDataSource'
在applicationContext.xml中配置数据源时,报错如下: Cannot resolve class or package 'dbcp' Cannot resolve class 'Ba ...
- Telephone interview with Youyou Tu
"Good News for the National Holiday!" Telephone interview with Youyou Tu following the ann ...
- getchar()、putchar()、gets()、puts()、cin.get()、cin.getline()、getline()
1.getchar: 原型为int getchar(void). 它从stdin里读取一个字符.返回值为用户输入的ASCⅡ码,出错返回-1. eg:c=getchar(). 2.putchar: 原型 ...