社区
网络编程
帖子详情
请教Socket编程高手?
xujian1988616
2011-02-23 02:56:27
我想将原先从串口读取的数据该从网口读取数据!我用的是VC MFC!我晓得用SOCKET编程可以实现!但任务比较紧急,学习来不及的!能否帮忙写个类,我只想弄个类似客户端的东西,从服务器读取数据!
...全文
261
20
打赏
收藏
请教Socket编程高手?
我想将原先从串口读取的数据该从网口读取数据!我用的是VC MFC!我晓得用SOCKET编程可以实现!但任务比较紧急,学习来不及的!能否帮忙写个类,我只想弄个类似客户端的东西,从服务器读取数据!
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
20 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
dongxiao1198
2011-02-24
打赏
举报
回复
我做过一个聊天室程序,是包括的传输文件和聊天的基于mfc和api的socket传输~给你网址去下吧就在csdn下载区~其中还对消息进行了ase128加密~对你应该有帮助~http://download.csdn.net/source/3031946
Wenxy1
2011-02-24
打赏
举报
回复
快学习下,有VC的基础,学socket API,一周内搞定.
xengine-qyt
2011-02-24
打赏
举报
回复
有那些不清楚的就说呗。你串口的数据是从哪儿来的?
xujian1988616
2011-02-23
打赏
举报
回复
我可没说网上的类我都看不懂!有些变量声明的不清楚而已啊!
快乐鹦鹉
2011-02-23
打赏
举报
回复
网上给的类你都看不懂,别人给的你更看不懂了。
8楼的你看懂了吗?
xujian1988616
2011-02-23
打赏
举报
回复
主要是现在没头绪,给点类参考下也行啊!网上其它的类变量声明的不清楚,看不大懂!
快乐鹦鹉
2011-02-23
打赏
举报
回复
去私活网吧
快乐鹦鹉
2011-02-23
打赏
举报
回复
那你是找人编程了,不是问技术问题的......
xujian1988616
2011-02-23
打赏
举报
回复
网上的实例当中有的实例的变量的声明的不清楚,看了叶不晓得有什么作用!
xujian1988616
2011-02-23
打赏
举报
回复
QQ联系也可以,非常的不解!
xujian1988616
2011-02-23
打赏
举报
回复
能帮我写个类吗?以前做的是串口,网口不熟悉!任务有紧急!
celerylxq
2011-02-23
打赏
举报
回复
//以下是客户端去连服务器,建立好socket(m_Connect)后从这个socket读数据即可
[code=C]/C++[/code]
int CMySocketTCP :: OnConnect(CString strIP,WORD port)
{
closesocket(m_Connect);
m_Connect = socket(AF_INET,SOCK_STREAM,0);
if (INVALID_SOCKET == m_Connect)
{
return 0;
}
sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.S_un.S_addr = inet_addr(strIP);
addr.sin_port = htons(port);
//设置为非阻塞方式连接
unsigned long ul = 1;
int err;
int ret = ioctlsocket(m_Connect, FIONBIO, (unsigned long*)&ul);
if(ret == SOCKET_ERROR)
{
err = WSAGetLastError();
closesocket(m_Connect);
m_Connect = NULL;
return FALSE;
}
TIMEVAL timeval;
fd_set r;
FD_ZERO(&r);
FD_SET(m_Connect, &r);
timeval.tv_sec = 1; //秒
timeval.tv_usec =200; //毫秒
//上面的代码是要connect在1.2秒之后返回,不管是否已经连接上,这样就不会阻塞啦
int tmp = connect(m_Connect, (SOCKADDR*)&addr, sizeof(SOCKADDR));//connect为阻塞函数,当连接不成功时会出现假死现象
ret = select(0, 0, &r, 0, &timeval);
if ( ret <= 0 )
{
err = WSAGetLastError();
closesocket(m_Connect);
m_Connect = NULL;
((CMainFrame *)AfxGetApp()->GetMainWnd())->P_TCPPara->GetDlgItem(IDC_STATIC_NETSTATUS)->SetWindowText("正在连接...");
return FALSE;
}
else
{
((CMainFrame*)AfxGetApp() ->GetMainWnd())->m_pDownLoadProc->ShowInfo("建立连接成功!");
::AfxMessageBox("建立连接成功!", MB_USER_MESSAGEBOX,MB_ICONINFORMATION);
((CMainFrame *)AfxGetApp()->GetMainWnd())->P_TCPPara->GetDlgItem(IDC_STATIC_NETSTATUS)->SetWindowText("建立连接成功!");
Sleep(1000);
ConnectSucc = 1;
WSAAsyncSelect(m_Connect,m_hWnd,WM_SOCKET_CLOSE,FD_CLOSE);
return 1;
}
//设回阻塞模式
ul = 0 ;
ret = ioctlsocket(m_Connect, FIONBIO, (unsigned long*)&ul); //返回之后,记得要设置为阻塞模式哟
return 0;
}
BOOL CMySocketTCP::InitSocket()
{//加载套接字库
WSADATA WSAData;
if (WSAStartup(MAKEWORD(2,0),&WSAData) != 0)
{
return FALSE;
}
return TRUE;
}
xujian1988616
2011-02-23
打赏
举报
回复
高手可以QQ联系!744031540
fishion
2011-02-23
打赏
举报
回复
http://hi.baidu.com/tooker/blog/item/7d9907f32bf94ecb0a46e0af.html
xujian1988616
2011-02-23
打赏
举报
回复
任务比较紧急,CSocket类没用过!麻烦指点下
xujian1988616
2011-02-23
打赏
举报
回复
/*****************************************************************
** 函数名:DealCommError
** 返 回:
** 错误代码。0:正常;1:本串口不是AVR
** 功能描述:清除本串口对应AVR的数据,并置错误标志
** 修改:
** 版本:v1.0.0
*****************************************************************/
int CSerialComm::DealCommError()
{
int err = 0, i, j;
// 清除对应AVR的数据
memset(&gSttWf, 0, sizeof(gSttWf));
memset(&gAnalog, 0, sizeof(gAnalog));
for (i=0; i<ParaTotalNum; i++)
{
for (j=0; j<4; j++)
{
gPara[i].Para[j] = 0;
}
}
memset(&gSysState, 0, sizeof(gSysState));
gSysState.ComError = TRUE;
return err;
}
/*****************************************************************
** 函数名:LocateAVR
** 返 回:
** 错误代码。0:找到包头;1:未找到包头
** 功能描述:定位AVR通讯协议包头位置
** 修改:
** 版本:v1.0.0
*****************************************************************/
int CSerialComm::LocateAVR()
{
int i, j, err = 1;
uInt8 sumCheck;
for (i=0; i<m_ComInfo.StrLen-AVRPackageLen; i++)
{
if ((170==m_ComInfo.RxStr[i])&&(170==m_ComInfo.RxStr[i+AVRPackageLen])) // 找到包头
{
sumCheck = CalSumCheck(m_ComInfo.RxStr+i, AVRPackageLen - 1);
if (sumCheck == m_ComInfo.RxStr[i+AVRPackageLen-1]) // 校验和正确
{
// 删除无效数据
for (j=i; j<m_ComInfo.StrLen; j++)
{
m_ComInfo.RxStr[j-i] = m_ComInfo.RxStr[j];
}
// 设置标志,并计算数据长度
m_ComInfo.FindHead = TRUE;
m_ComInfo.StrLen = m_ComInfo.StrLen - i;
err = 0;
break;
}
}
}
if (!m_ComInfo.FindHead) //未找到包头,则删除所有数据
{
m_ComInfo.StrLen = 0;
}
return err;
}
/*****************************************************************
** 函数名:AnalyseAVR
** 返 回:
** 错误代码。0:正常;1:数据通道号出错;2:数据校验码出错;3:数据包头出错
** 功能描述:分析AVR通讯协议,将结果存入全局变量中
** 修改:
** 版本:v1.0.0
*****************************************************************/
int CSerialComm::AnalyseAVR()
{
int i, j, k, err=0;
uInt8 sumCheck, chNo;
float temp;
// 若数据太短,则留到下一循环处理
if (m_ComInfo.StrLen < AVRPackageLen*2)
{
err = 1;
return err;
}
// 解释协议,将数据写入各个变量
for (i=0; (i+1)*AVRPackageLen<(m_ComInfo.StrLen+1); i++)
{
if (170 == m_ComInfo.RxStr[i*AVRPackageLen]) // 包头正确
{
sumCheck = CalSumCheck(m_ComInfo.RxStr+i*AVRPackageLen, AVRPackageLen-1);
if (sumCheck == m_ComInfo.RxStr[i*AVRPackageLen+AVRPackageLen-1]) // 校验和正确
{
chNo = m_ComInfo.RxStr[i*AVRPackageLen+1];
// 通道号0x0~0x21
if((chNo>=0)&&(chNo<AnalogNum))
{
// 是模拟状态量
if(chNo < AnalogNum)
{
// 判断是否为负,为负则求补码asd
if(m_ComInfo.RxStr[i*AVRPackageLen+3]<128)
{
temp=(float)(m_ComInfo.RxStr[i*AVRPackageLen+2]+256*m_ComInfo.RxStr[i*AVRPackageLen+3]);
}
else
{
temp=(float)(m_ComInfo.RxStr[i*AVRPackageLen+2]+256*m_ComInfo.RxStr[i*AVRPackageLen+3]-65536);
}
// 除以相应通道的放大倍数
temp=temp/AnalogueGain[chNo];
gAnalog[chNo]=temp;
}
// 写状态波形
for(j=0;j<SttWfNum;j++)
{
if(m_ComInfo.RxStr[i*AVRPackageLen+5+j*2]<128)
{
temp=(float)(m_ComInfo.RxStr[i*AVRPackageLen+4+j*2]+256*m_ComInfo.RxStr[i*AVRPackageLen+5+j*2]);
}
else
{
temp=(float)(m_ComInfo.RxStr[i*AVRPackageLen+4+j*2]+256*m_ComInfo.RxStr[i*AVRPackageLen+5+j*2]-65536);
}
temp=temp/10000;
k=(int)gSttWf[j][SttWfPointNum-1]; // 表头
gSttWf[j][k]=temp;
if(++k==SttWfPointNum-1)
{
k=k-(SttWfPointNum-1);
}
gSttWf[j][SttWfPointNum-1]=(float)k;
}
}
//保存参数到Parameters
else if((chNo>=128)&&(chNo<=140))
{
if(m_ComInfo.RxStr[i*AVRPackageLen+14]==0x80) // RAM中的参数
{
k=2;
gSysState.ParaUpdated = TRUE;
gSysState.ParaUpdateNo = chNo-127; //参数组号,1~10
}
else if(m_ComInfo.RxStr[i*AVRPackageLen+14]==0xC0) // E2PROM中的参数
{
k=1;
gSysState.ParaUpdated = TRUE;
}
else // Flash中参数
{
k=0;
gSysState.ParaUpdated = TRUE;
}
for(j=0; j<6; j++) // 每个包有6个参数
{
if(m_ComInfo.RxStr[i*AVRPackageLen+3+j*2]<128)
{
gPara[(chNo-128)*6+j].Para[k] = m_ComInfo.RxStr[i*AVRPackageLen+2+j*2]+256*m_ComInfo.RxStr[i*AVRPackageLen+3+j*2];
}
else
{
gPara[(chNo-128)*6+j].Para[k] = m_ComInfo.RxStr[i*AVRPackageLen+2+j*2]+256*m_ComInfo.RxStr[i*AVRPackageLen+3+j*2]-65536;
}
//更新当前参数为运行参数
if (2 == k)
{
gPara[(chNo-128)*6+j].Para[3] = gPara[(chNo-128)*6+j].Para[2];
}
}
}
else
{
err = 1; // 数据通道号出错
}
}
else
{
err = 2; // 数据校验和出错
}
}
else
{
err = 3; // 包头出错
}
}
if (0 == err) // 没有错误,将处理过的数据删除
{
m_ComInfo.StrLen = m_ComInfo.StrLen - i*AVRPackageLen;
for (j=0; j<m_ComInfo.StrLen; j++)
{
m_ComInfo.RxStr[j] = m_ComInfo.RxStr[j+i*AVRPackageLen];
}
m_ComInfo.ErrCount = 0;
}
else // 出错,则丢弃当前所有数据
{
m_ComInfo.StrLen = 0;
m_ComInfo.FindHead = FALSE;
}
return err;
}
uInt8 CSerialComm::CalSumCheck(uInt8 *Str, uInt32 Length)
{
uInt8 sumCheck;
uInt32 temp,i;
temp=0;
for(i=0; i<Length; i++)
{
temp = temp+Str[i];
}
sumCheck=temp-(temp/256)*256;
return sumCheck;
}
/*****************************************************************
** 函数名:SendCommand
** 输 入:
** Data1~3:三个字节命令
** 返 回:
** 错误代码。
** 功能描述:
** 向AVR发送控制命令,第一个字节是0xBB,第五个字节是校验码,因此需要传入中间三个字节数据。
** 修改:将SendCommand从CGlobalFunc改到CSerialComm中,删除Des参数,改为由调用者判断串口编号
** 版本:v1.0.1
*****************************************************************/
int CSerialComm::SendCommand(uInt8 Data1, uInt8 Data2, uInt8 Data3)
{
uInt8 sendBuf[5];
DWORD sendLen;
int err = 0;
sendBuf[0] = 0xBB;
sendBuf[1] = Data1;
sendBuf[2] = Data2;
sendBuf[3] = Data3;
sendBuf[4] = CalSumCheck(sendBuf, 4);
WriteFile(m_hCom, sendBuf, 5, &sendLen, NULL);
Sleep(WaitForWriteCom);
return err;
}
/*****************************************************************
** 函数名:GetComHandle
** 返 回:
** 串口句柄
** 功能描述:
** 获取当前串口类对应的串口句柄。目前仅用于AVR通讯
** 修改:
** 版本:v1.0.0
*****************************************************************/
HANDLE CSerialComm::GetComHandle()
{
return m_hCom;
}
/*****************************************************************
** 函数名:GetErrCnt
** 返 回:
** 串口出错次数
** 功能描述:
** 获取当前串口类对应的串口错误次数。目前仅用于AVR通讯
** 修改:
** 版本:v1.0.0
*****************************************************************/
uInt8 CSerialComm::GetErrCnt()
{
return m_ComInfo.ErrCount;
}
xujian1988616
2011-02-23
打赏
举报
回复
补充下,原先写的串口类奉上!
#include "stdafx.h"
#include "ECU.h"
#include "ECUDlg.h"
#include "SerialComm.h"
#include "GlobalFunc.h"
#include "memory.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
// 全部变量声明
extern Real32 gSttWf[SttWfNum][SttWfPointNum];
extern Real32 gAnalog[AnalogNum];
extern ParaStruct gPara[ParaGroupNum*13];
extern SysState gSysState;
extern int AnalogueGain[AnalogNum];
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CSerialComm::CSerialComm()
{
}
CSerialComm::~CSerialComm()
{
}
/*****************************************************************
** 函数名:Init
** 输 入:
** ComName:串口资源名
** ComNo:串口编号,1、2为AVR,4为DCS
** 返 回:
** 错误代码。0:初始化成功;其它:GetLastError()返回结果
** 功能描述:串口初始化
** 修改:
** 版本:v1.0.0
*****************************************************************/
int CSerialComm::Init(LPCSTR ComName)
{
int err = 0;
// 初始化串口Info结构体
memset(&m_ComInfo, 0, sizeof(ComInfo));
// 打开串口
m_hCom = CreateFile(ComName,
GENERIC_READ|GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
// 串口打开错误
if (INVALID_HANDLE_VALUE == m_hCom)
{
err = GetLastError();
}
else
{
// 设置串口
ConfigCom();
}
// 初始化串口数据
memset(&m_ComInfo, 0, sizeof(ComInfo));
return err;
}
/*****************************************************************
** 函数名:ConfigCom
** 返 回:
** 错误代码。0:设置成功;其它:GetLastError()返回结果
** 功能描述:串口设置。设置串口波特率和缓冲区大小
** 修改:
** 版本:v1.0.0
*****************************************************************/
int CSerialComm::ConfigCom()
{
int err = 0;
DCB dcb;
// 获取串口设置,若失败则返回错误代码
if(!GetCommState(m_hCom,&dcb))
{
err = GetLastError();
return err;
}
dcb.BaudRate = CBR_9600; //baudRate=9600
dcb.ByteSize = 8; //8 bit data
dcb.fParity = FALSE; //no parity checkout
dcb.StopBits = ONESTOPBIT; //1 stop bit
dcb.fOutxDsrFlow = FALSE;
dcb.fRtsControl = RTS_CONTROL_DISABLE;
dcb.fOutX = FALSE;
dcb.fInX = FALSE;
// 清除串口缓冲,并中止任何读写操作
PurgeComm(m_hCom, PURGE_TXABORT|PURGE_TXCLEAR|PURGE_RXABORT|PURGE_RXCLEAR);
// 设置串口Buffer
SetupComm(m_hCom, MaxComBuffer, MaxComBuffer);
// 设置串口,若失败则返回错误代码
if (!SetCommState(m_hCom,&dcb))
{
err = GetLastError();
}
return err;
}
/*****************************************************************
** 函数名:Release
** 返 回:
** 错误代码。0:释放成功;1:串口未打开
** 功能描述:串口释放。清除串口缓冲区,释放串口资源
** 修改:
** 版本:v1.0.0
*****************************************************************/
int CSerialComm::Release()
{
int err = 0;
if (INVALID_HANDLE_VALUE != m_hCom)
{
PurgeComm(m_hCom, PURGE_TXABORT|PURGE_TXCLEAR|PURGE_RXABORT|PURGE_RXCLEAR);
CloseHandle(m_hCom);
}
else
{
err = 1;
}
return err;
}
/*****************************************************************
** 函数名:ReadCom
** 返 回:
** 错误代码。0:正常;1:串口无数据;2:串口未打开
** 功能描述:读串口数据,并查找包头,分析协议。若出现错误,则累加错误计数器
** 修改:
** 版本:v1.0.0
*****************************************************************/
int CSerialComm::ReadCom()
{
int err = 0;
COMSTAT ComStat;
DWORD Err, RxLen;
if (INVALID_HANDLE_VALUE != m_hCom)
{
// 清除串口错误,并得到串口状态信息
ClearCommError(m_hCom, &Err, &ComStat);
// 得到串口Buffer中的字符串长度
RxLen = ComStat.cbInQue;
if (0 == RxLen) // 若没有数据,则不处理
{
err = 1;
}
else
{
if (RxLen > 1024) // 如果超过1024则只读1024个字节
{
RxLen = 1024;
TRACE("Data in Com buffer is too many!\n");
}
// 读串口数据到RxStr
ReadFile(m_hCom, &m_ComInfo.RxStr[m_ComInfo.StrLen], RxLen, &RxLen, NULL);
m_ComInfo.StrLen = m_ComInfo.StrLen + RxLen;
// 如果未找到包头,则先查找包头
if (!m_ComInfo.FindHead)
{
err = LocateAVR();
}
// 如果已经找到包头,则进行协议分析
if (m_ComInfo.FindHead)
{
err = AnalyseAVR();
}
}
}
else // 串口打开错误
{
err = 2;
}
if (0 != err) // 若出现错误,则累加错误计数器
{
if (255 != m_ComInfo.ErrCount) // 若错误计数器小于255,则加1
{
m_ComInfo.ErrCount++;
}
}
// 如果错误计数器大于4,则认为通讯故障,同时清除该套数据。
// 之所以选择5作为判断,是为了故障后只执行一次DealCommError()
if (5 == m_ComInfo.ErrCount)
{
DealCommError();
}
return err;
}
快乐鹦鹉
2011-02-23
打赏
举报
回复
既然你是用VC MFC,那么你只要用class wizard从CSocket派生一个子类,然后响应OnReceive接收数据就行了。
Eleven
2011-02-23
打赏
举报
回复
看看Windows网络编程的例子
socket/io(1)、Linux的
socket编程
详解
本文详细介绍了Linux下的
Socket编程
原理及实现过程,涵盖了进程间通信的基础概念、Socket的定义与用途、TCP和UDP的区别,以及
Socket编程
的基本接口函数。并通过一个具体的编程实例展示了服务器与客户端的通信流程。
Socket编程
详解
本文深入介绍了Linux环境下的
Socket编程
,包括套接字概念、网络字节序、
Socket编程
基础及函数详解。讲解了从创建套接字、绑定地址、监听连接到接受和关闭连接的全过程,并通过示例展示了
Socket编程
中的错误处理。此外,还提供了简单的服务器与客户端交互的项目练习。
Socket 简介与 Java Socket 编程示例
本文介绍Socket的概念、工作原理及应用场景,重点讲解Java中的
Socket编程
,包括ServerSocket与Socket的使用方法,并提供完整的示例代码。
Raw Socket和
Socket编程
本文深入浅出地介绍了
Socket编程
的基本概念及工作原理,并通过一个简单的TCP客户端与服务器端通信实例,展示了如何利用Socket进行网络编程。
【Java TCP/IP Socket】
Socket编程
大合集
本文整理了Java TCP/IP
Socket编程
系列文章,包括TCP和UDP Socket的基础知识,自定义协议消息的构建与解析,线程池TCP服务器,NIO Socket对比,以及TCP通信中可能出现的问题与解决策略,是学习和复习
Socket编程
的宝贵资料。
网络编程
18,357
社区成员
64,165
社区内容
发帖
与我相关
我的任务
网络编程
VC/MFC 网络编程
复制链接
扫一扫
分享
社区描述
VC/MFC 网络编程
c++
c语言
开发语言
技术论坛(原bbs)
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章