用MFC建立了一个SOCKET通信客户端,如何将传感器传输的数据持续发送到服务器端。

zyd3123733 2018-01-04 03:57:10
#include "stdafx.h"
#include "六维力采集demo.h"
#include "六维力采集demoDlg.h"
#include "afxdialogex.h"
#include "MySocketC.h"



#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// C六维力采集demoDlg 对话框

SOCKET sockConn;
DWORD WINAPI Socket_ListenProc(LPVOID lpParam);
DWORD WINAPI Socket_RecvProc(LPVOID lpParam);

BOOL m_bListen; //侦听标志
CString ip; //记录客户端ip地址

DWORD WINAPI Socket_ListenProc(LPVOID lpParam)
{
SOCKET sock = ((LISTENPARAM*)lpParam)->sock; //本机socket
HWND hwnd = ((LISTENPARAM*)lpParam)->hwnd; //对话框句柄

SOCKADDR_IN addrClient;
int nLen = sizeof(SOCKADDR);

while (m_bListen) //监听标识符
{
sockConn = accept(sock,(SOCKADDR*)&addrClient,&nLen);

if (INVALID_SOCKET != sockConn)
{
CString str;
str.Format(_T("%s"),(CString)inet_ntoa(addrClient.sin_addr));

RECVPARAM RecvParam;
RecvParam.hwnd = hwnd;
RecvParam.sock = sockConn;
RecvParam.ip= str;
ip=str;
//开一个接收数据处理的线程用来接收数据
HANDLE hThread = CreateThread(NULL, 0, Socket_RecvProc, (LPVOID)&RecvParam, 0, NULL);

}
}
return 0;
}

DWORD WINAPI Socket_RecvProc(LPVOID lpParam)
{
SOCKET sock = ((RECVPARAM*)lpParam)->sock;
HWND hwnd = ((RECVPARAM*)lpParam)->hwnd;

char recvBuf[100]={0};
int nRetVal;
while (TRUE)
{
nRetVal = recv(sock,recvBuf,8,0);//第三个参数为接收数据的长度,本传感器固定接收大小为8

if ((INVALID_SOCKET == nRetVal) || (0==nRetVal) || (nRetVal==WSAECONNRESET))
break;

//如果成功接收8字节则发送接收消息,调用相应的接收处理函数进行数据处理
if (nRetVal==8)
::SendMessage(hwnd,WM_RECVDATA,(WPARAM)0,(LPARAM)recvBuf);
}
return 0;
}

C六维力采集demoDlg::C六维力采集demoDlg(CWnd* pParent /*=NULL*/)
: CDialogEx(C六维力采集demoDlg::IDD, pParent)
, m_Port(6001)
, m_DataReceive()
, m_DataSend(_T(""))
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_FX = 0.0f;
m_FY = 0.0f;
m_FZ = 0.0f;
m_MX = 0.0f;
m_MY = 0.0f;
m_MZ = 0.0f;
m_FrameNo = 0;
m_IP = _T("");
FreNum=0;

}

void C六维力采集demoDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Text(pDX, IDC_FX, m_FX);
DDX_Text(pDX, IDC_FY, m_FY);
DDX_Text(pDX, IDC_FZ, m_FZ);
DDX_Text(pDX, IDC_MX, m_MX);
DDX_Text(pDX, IDC_MY, m_MY);
DDX_Text(pDX, IDC_MZ, m_MZ);
DDX_Text(pDX, IDC_Frame, m_FrameNo);
DDX_Text(pDX, IDC_IP, m_IP);
DDX_Text(pDX, IDC_Port, m_Port);
DDX_Control(pDX, IDC_Connect, m_ConPC);
DDX_Control(pDX, IDC_IPADDRESS1, m_ipaddress);
DDX_Text(pDX, IDC_DataSend, m_DataSend);

}

BEGIN_MESSAGE_MAP(C六维力采集demoDlg, CDialogEx)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_MESSAGE(WM_RECVDATA,OnRecvData)
ON_BN_CLICKED(IDC_BTNCONNECT, &C六维力采集demoDlg::OnBnClickedBtnconnect)
ON_BN_CLICKED(IDCANCEL, &C六维力采集demoDlg::OnBnClickedCancel)
ON_BN_CLICKED(IDC_Begin, &C六维力采集demoDlg::OnBnClickedBegin)
ON_BN_CLICKED(IDC_Stop, &C六维力采集demoDlg::OnBnClickedStop)
ON_WM_TIMER()
ON_BN_CLICKED(IDC_Connect, &C六维力采集demoDlg::OnBnClickedConnect)
ON_BN_CLICKED(IDC_SendData, &C六维力采集demoDlg::OnBnClickedSenddata)
ON_BN_CLICKED(IDC_Change, &C六维力采集demoDlg::OnBnClickedChange)
END_MESSAGE_MAP()


// C六维力采集demoDlg 消息处理程序

BOOL C六维力采集demoDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
m_connect = false;
m_ipaddress.SetWindowTextW(_T("192.168.1.197"));
// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标

// TODO: 在此添加额外的初始化代码
//以下是触发SOCKET。
//为以后创建套接字做准备
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );
err = WSAStartup( wVersionRequested, &wsaData );
// 由于对话框已关闭,所以将返回 FALSE 以便退出应用程序,
// 而不是启动应用程序的消息泵。

if(err==0)
{
AfxMessageBox(_T("触发SOCKET成功"));
}
else
{
AfxMessageBox(_T("触发SOCKET失败"));
}

//设定定时器实时刷新对话框中的数据
SetTimer(1,100,NULL);
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}




LRESULT C六维力采集demoDlg::OnRecvData(WPARAM wParam,LPARAM lParam)
{
//CString ip= _T("0");
char* pRecvData;
pRecvData = (char *)lParam;
RecvData(ip,pRecvData);
return 0;
}

//接收处理函数
//本函数处理接收过来的数据,即由接收的原始数据得到6个通道的具体值(电压模拟值,可供后续开发使用)
//数据处理过程算法固定(根据下位机发送数据的机制)
//其中每一帧数据分上一半和下一半进行处理,在程序中用FIRST进行标识
//ONE标识第一次按采集按钮,即第一次采集
void C六维力采集demoDlg::RecvData(CString ip,char *pData)
{

m_IP=ip;//保存客户端的ip地址
if (ONE && !FIRST)
{
ONE = FALSE;
FIRST= TRUE;
return ;
}
short num, data1, data2, data;
int g_Frequency=500;//采样频率默认为1000,可以根据需要进行改动
data = 0x00FF;

if (FIRST) //前一半
{
FIRST= FALSE;
if (FreNum != 5000/g_Frequency)
return ;

//FrameID为下位机发送的帧号,依据下位机发送机制进行处理,可能会出现帧号非规律化(因为下位机原因)
//建议通过让帧号从1开始递增的方法记录帧号,以便后续使用
buff.FrameID =(BYTE)pData[2]*256*256*256+(BYTE)pData[3]*256*256+(BYTE)pData[0]*256+(BYTE)pData[1];
m_FrameNo++;//帧号自增
data1 = data2 = 0;
data1 = pData[4]*256;
data2 = pData[5] & data;
num = data1 + data2;
buff.AD[0] = num/3.2768;

data1 = data2 = 0;
data1 = pData[6]*256;
data2 = pData[7] & data;
num = data1 + data2;
buff.AD[2] = num/3.2768;
}
else //后一半
{
FIRST = TRUE;
if (FreNum == 5000/g_Frequency)
{
data1 = data2 = 0;
data1 = pData[0]*256;
data2 = pData[1] & data;
num = data1 + data2;
buff.AD[4] = num/3.2768;

data1 = data2 = 0;
data1 = pData[2]*256;
data2 = pData[3] & data;
num = data1 + data2;
buff.AD[1] = num/3.2768;

data1 = data2 = 0;
data1 = pData[4]*256;
data2 = pData[5] & data;
num = data1 + data2;
buff.AD[3] = num/3.2768;

data1 = data2 = 0;
data1 = pData[6]*256;
data2 = pData[7] & data;
num = data1 + data2;
buff.AD[5] = num/3.2768;

FreNum=1;
return;

}
FreNum ++;
}
m_IP=ip; //设定客户端的ip

//以下是6个通道的原始电压值
//分别对应6个对话框中的值,电压值可供后续开发处理使用
m_FX=buff.AD[0];
m_FY=buff.AD[1];
m_FZ=buff.AD[2];
m_MX=buff.AD[3];
m_MY=buff.AD[4];
m_MZ=buff.AD[5];

请问大手子们这六个电压值后续如何调用,想实现将其数据持续发送到服务器端。
...全文
1242 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
zyd3123733 2018-01-12
  • 打赏
  • 举报
回复
引用 10 楼 tajon1226 的回复:
直接发收到的数据你敢信吗? 最起码用个简单的协议包! 命令码 + 设备编号 + 数据长度 + 数据 + 校验
好的,大佬有没有相关好的资料给推荐一下,新入门
zyd3123733 2018-01-11
  • 打赏
  • 举报
回复
顶一下帖。。。有没有大佬能解决的。。
走好每一步 2018-01-11
  • 打赏
  • 举报
回复
直接发收到的数据你敢信吗? 最起码用个简单的协议包! 命令码 + 设备编号 + 数据长度 + 数据 + 校验
赵4老师 2018-01-09
  • 打赏
  • 举报
回复
不知道有多少前人掉在TCP Socket send(人多)send(病少)send(财富) recv(人多病)recv(少财富) 陷阱里面啊! http://bbs.csdn.net/topics/380167545
sichuanwww 2018-01-09
  • 打赏
  • 举报
回复
zyd3123733 2018-01-08
  • 打赏
  • 举报
回复
引用 4 楼 wangningyu 的回复:
把下位机采集的数据重新打包:站号(设备序号) + 长度 + CRC校验 + 采集数据,发给服务端再重新解包即可
这个是厂家给的DEMO。不能直接利用已经采集好的这六个数据么
sevancheng 2018-01-08
  • 打赏
  • 举报
回复
这个中文命名也是醉了。。。
汪宁宇 2018-01-06
  • 打赏
  • 举报
回复
把下位机采集的数据重新打包:站号(设备序号) + 长度 + CRC校验 + 采集数据,发给服务端再重新解包即可
zyd3123733 2018-01-05
  • 打赏
  • 举报
回复
还有没有大佬啊。。。上面的回答不可用。。BYTE和VOID不兼容。send不接受两个参数
zyd3123733 2018-01-04
  • 打赏
  • 举报
回复
引用 1 楼 jason_wentzel 的回复:
// 假设6个数据都是4个字节的: BYTE sendbuff[1024] = {0}; CopyMemory(sendbuff[0],&m_FX,4); CopyMemory(sendbuff[4],&m_FY,4); CopyMemory(sendbuff[8],&m_FZ,4); CopyMemory(sendbuff[12],&m_MX,4); CopyMemory(sendbuff[16],&m_MY,4); CopyMemory(sendbuff[20],&m_MZ,4); send((char*)sendbuff,4*6);
就是具体控件发送该怎么编写,求详解,感激不尽
孤客天涯 2018-01-04
  • 打赏
  • 举报
回复
// 假设6个数据都是4个字节的: BYTE sendbuff[1024] = {0}; CopyMemory(sendbuff[0],&m_FX,4); CopyMemory(sendbuff[4],&m_FY,4); CopyMemory(sendbuff[8],&m_FZ,4); CopyMemory(sendbuff[12],&m_MX,4); CopyMemory(sendbuff[16],&m_MY,4); CopyMemory(sendbuff[20],&m_MZ,4); send((char*)sendbuff,4*6);

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧