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 ...
随机推荐
- 基于OpenGL编写一个简易的2D渲染框架-05 渲染文本
阅读文章前需要了解的知识:文本渲染 https://learnopengl-cn.github.io/06%20In%20Practice/02%20Text%20Rendering/ 简要步骤: 获 ...
- 配置tomcat日志分割
由于Tomcat在默认情况下会将没有经过配置的web应用所产生的日志输出已及其本身的日志内容都输出到这个文件中,那么随着时间的推移,这个文件的尺寸将会越来越大,当需要检查日志内容时间会导致文件难以打开 ...
- Java Magic. Part 1: java.net.URL
Java Magic. Part 1: java.net.URL @(Base)[JDK, url, magic, 黑魔法] 英文原文 转载请写明:原文地址 系列文章: -Java Magic. Pa ...
- Linux CentOS7中 设置IP地址、网关DNS
cd /etc/sysconfig/network-scripts/ #进入网络配置文件目录 vi ifcfg-eno16777736 #编辑配置文件,此处eno后边的编号因电脑而易 TYPE ...
- PPT汇报 评审表
评审表 团队编号 团队名称 团队项目名称 格式评审 内容评审 PPT评审 演讲评审 优点 存在问题(至少提3点) 建议 01 牛肉面不要牛肉不要面 02 正义联盟 我是一个图书小平台 03 什么队 & ...
- Python在pycharm中编程时应该注意的问题汇总
1.缩进问题 在 pycharm 中点击 enter 自动进行了换行缩进,此时应该注意:比如 if else 语句,后面跟着打印输出 print 的时候,一定注意是要if语句下的输出还是else ...
- fio 测试磁盘
root@rook-test:/# ceph osd status+----+-----------------------------+-------+-------+--------+------ ...
- ORACLE用户永不被锁
alter profile default limit FAILED_LOGIN_ATTEMPTS UNLIMITED;
- VideoView的全屏问题
package com.bi.standardcompuse.app.widgets; import android.content.Context;import android.util.Attri ...
- Spring框架之Bean的作用范围和生命周期的注解
1. Bean的作用范围注解 * 注解为@Scope(value="prototype"),作用在类上.值如下: * singleton -- 单例,默认值 * prototype ...