代码

本文介绍了一个MML客户端如何实现与服务器的连接、消息的编码与解码、发送及接收等核心功能。针对不同类型的MML消息,如心跳消息和普通指令消息,详细展示了其处理流程和技术细节。

// Deal.cpp: implementation of the CDeal class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "ClientMML.h"
#include "Deal.h"
#include<winsock2.h>
#include<stdio.h>
#include "Shlwapi.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CDeal::CDeal()
{

}

CDeal::~CDeal()
{

}

/************************连接服务器*************************/
int CDeal::connectMML(int& m_sockfd, CString& m_ip, int& m_port)
{
  SOCKADDR_IN m_server_addr;
  int m_result;
  memset((char*)&m_server_addr,'/0',(int)sizeof(m_server_addr));
  //Socket地址结构体的创建
  m_server_addr.sin_family = AF_INET;
  m_server_addr.sin_addr.S_un.S_addr = inet_addr(m_ip);
  m_server_addr.sin_port = htons( m_port );
  //创建流式套接字,基于TCP(SOCK_STREAM)
  m_sockfd = socket( AF_INET, SOCK_STREAM, 0 );
  if (0 >= m_sockfd)
  {
   AfxMessageBox("socket creat failed/n");
   exit(0);
  }
  //Socket的内部函数,建立客户端到服务器的连接
  m_result = connect(m_sockfd, (SOCKADDR*)&m_server_addr, sizeof(SOCKADDR));
  if (0 != m_result)
  {
   AfxMessageBox("connect server failed/n");
   exit(0);
  }
  return 1;

}


/**************MML客户端消息编码封装成可识别消息****************/
int CDeal::Encode(MsgInfo & sendMsg,char * sendBuff, int & sendLen, int send_type)
{
  //此处省略异常处理过程

  //如果是心跳消息,编码方式如下
  if (TYPE_OF_HB_MSG == send_type)
  {
   int temp_len;
   char * p_num, hb_checksum [MAX_HB_CHCKSUM];
   temp_len = 0;
   strncpy(sendBuff+ temp_len,MSG_STARTTAG, MSG_STARTTAG_LEN);
   temp_len += MSG_STARTTAG_LEN;
         p_num = Int2ToHex(HB_MSG_LEN);
   strncpy(sendBuff + temp_len, p_num, MAX_HB_MSG_LEN);
   temp_len += MAX_HB_MSG_LEN;
   strncpy (sendBuff + temp_len, HB_CONTENT, MAX_HB_CONTENT_LEN);
   temp_len = MSG_STARTTAG_LEN + MAX_HB_MSG_LEN;
   GetChkSum(MAX_HB_MSG_LEN,sendBuff + temp_len,hb_checksum);
   temp_len = HB_MSG_LEN - MAX_HB_CHCKSUM;
   strncpy(sendBuff + temp_len, hb_checksum, MAX_HB_CHCKSUM);
   printf("/ncode HB secceed!/n%s",sendBuff);
   return Success;
  }
  //如果是普通消息,编码如下
  int msglen,cmdlen,len;
  char *p,chksum[MSG_CHKSUM_LEN];
  char *pTx[ ] = { "TXBEG" , "TXCON"  , "TXCAN" , "TXEND" };
  char *pDlg[ ] = { "DLGLGN" , "DLGBEG"  , "DLGCON" , "DLGEND" };
  //打印发送的消息
  PrintMsg(sendMsg);
  //计算消息长度
  cmdlen=strlen(sendMsg.cmd);
  msglen=MAX_HEAD_LEN+cmdlen;
  len=(4 - msglen % 4);
  msglen+=len;
  sendLen=msglen+MSG_COMM_LEN;
  memset(sendBuff,' ',MAX_MSG_LEN);
  len=0;
  //拼装消息开始标志
 
  strncpy(sendBuff+len, MSG_STARTTAG, MSG_STARTTAG_LEN);
  len+=MSG_STARTTAG_LEN;
  //拼装消息长度
      p=Int2ToHex(msglen);

  strncpy(sendBuff+len, p, MSG_INFOLEN_LEN);
  len+=MSG_INFOLEN_LEN;
  //拼装消息头
 
  strncpy(sendBuff+len, MSG_VERSION, MAX_LEN_VERSION);
  len+=MAX_LEN_VERSION;
  strncpy(sendBuff+len, MSG_TERMINAL, MAX_LEN_TERMINAL);
  len+=MAX_LEN_TERMINAL;
  strncpy(sendBuff+len,sendMsg.service, strlen(sendMsg.service));
  len+=MAX_LEN_SERVNAME;
  //拼装会话头
 
     p=Int4ToHex(sendMsg.snLogin);
  strncpy(sendBuff+len, p, MAX_LEN_DLGID);
  len+=MAX_LEN_DLGID;
  strncpy(sendBuff+len,pDlg[sendMsg.dlgCtrl],strlen(pDlg[sendMsg.dlgCtrl]));
  len+=MAX_LEN_DLGCTRL;
  strncpy(sendBuff+len, MSG_DLGRSVD, MAX_LEN_DLGRSVD);
  len+=MAX_LEN_DLGRSVD;
  //拼装事务头
  
 // p=Int4ToHex(sendMsg.sequence);
  sprintf(p, "%4x", sendMsg.sequence);
  strncpy(sendBuff+len, p, MAX_LEN_TXID);
  len+=MAX_LEN_TXID;
  strncpy(sendBuff+len,pTx[sendMsg.txCtrl],strlen(pTx[sendMsg
  .txCtrl]));
  len+=MAX_LEN_TXCTRL;
  strncpy(sendBuff+len, MSG_TXRSVD, MAX_LEN_TXRSVD);
  len+=MAX_LEN_TXRSVD;
  //拼装操作信息
  strncpy(sendBuff+len, sendMsg.cmd, cmdlen);
  //拼装校验和
 
  len=MSG_STARTTAG_LEN + MSG_INFOLEN_LEN;
  GetChkSum(msglen,sendBuff+len,chksum);
  len=sendLen-MSG_CHKSUM_LEN;
  strncpy(sendBuff+len, chksum, MSG_CHKSUM_LEN);
  return Success;
}


/***********对接受到的消息进行解码****************/
int CDeal::Decode(MsgInfo &recMsg,char* recBuff,int& recLen, int recv_type)
{
  //此处省略异常处理过程

  int msglen,len,tmpInt;
  char chksum[MSG_CHKSUM_LEN],tmpStr[MAX_MSG_LEN];
  char *pTx[ ] = { "TXBEG" , "TXCON"  , "TXCAN" , "TXEND" };
  char *pDlg[ ] = { "DLGLGN" , "DLGBEG"  , "DLGCON" , "DLGEND" };
  len=0;
  //解码消息开始标志
 
  strncpy(tmpStr, recBuff+len, MSG_STARTTAG_LEN);
  tmpStr[MSG_STARTTAG_LEN]='/0';
  len+=MSG_STARTTAG_LEN;
  if(strncmp(tmpStr,MSG_STARTTAG,MSG_STARTTAG_LEN) != 0)
  {
   printf("Msg head error.");
   return NotCMD;
  }
  //解码消息长度
  strncpy(tmpStr, recBuff+len, MSG_INFOLEN_LEN);
  tmpStr[MSG_INFOLEN_LEN]='/0';
  len+=MSG_INFOLEN_LEN;
        HexToInt2(tmpStr,tmpInt);
     msglen=tmpInt;
  if ( recv_type == TYPE_OF_CMD_MSG )
  {
   if(msglen+MSG_COMM_LEN != recLen)
   {
    printf("Msg length error.");
    return Failure;
   }
  }
  //如果是心跳消息,解码方式如下
  if ( recv_type == TYPE_OF_HB_MSG )
  {
   tmpInt=HB_MSG_LEN;
   char HBtempStr[HB_MSG_LEN],HBStr[HB_MSG_LEN];
   strncpy(HBtempStr, recBuff, tmpInt);
   HBtempStr[tmpInt]='/0';
   StrTrim(HBtempStr," ");
   strcpy(HBStr,"HBHB");
   for (int i=0; i<4; i++)
   {
    if( recBuff[MSG_STARTTAG_LEN+MAX_HB_MSG_LEN+i]!=HBStr[i])
    {
     return Failure;
    }
   }
   return Success;
  }
  //如果是普通消息,解码如下
  //解码消息头
 
  strncpy(tmpStr, recBuff+len, MAX_LEN_VERSION);
  tmpStr[MAX_LEN_VERSION]='/0';
  len+=MAX_LEN_VERSION;
  StrTrim(tmpStr," ");
  strncpy(tmpStr, recBuff+len, MAX_LEN_TERMINAL);
  tmpStr[MAX_LEN_TERMINAL]='/0';
  len+=MAX_LEN_TERMINAL;
  StrTrim(tmpStr," ");
  strncpy(tmpStr, recBuff+len, MAX_LEN_SERVNAME);
  tmpStr[MAX_LEN_SERVNAME]='/0';
  len+=MAX_LEN_SERVNAME;
  StrTrim(tmpStr," ");
  strcpy(recMsg.service,tmpStr);
  //解码会话头
 
  strncpy(tmpStr, recBuff+len, MAX_LEN_DLGID);
  tmpStr[MAX_LEN_DLGID]='/0';
  len+=MAX_LEN_DLGID;
  HexToInt4(tmpStr,tmpInt);
  recMsg.snLogin=tmpInt;
  strncpy(tmpStr, recBuff+len, MAX_LEN_DLGCTRL);
  tmpStr[MAX_LEN_DLGCTRL]='/0';
  len+=MAX_LEN_DLGCTRL;
  StrTrim(tmpStr," ");
  for(tmpInt=0;tmpInt<4;tmpInt++) if(strcmp(pDlg[tmpInt],tmpStr)==0) break;
  recMsg.dlgCtrl=tmpInt;
  strncpy(tmpStr, recBuff+len, MAX_LEN_DLGRSVD);
  tmpStr[MAX_LEN_DLGRSVD]='/0';
  len+=MAX_LEN_DLGRSVD;
  //解码事务头
 
  strncpy(tmpStr, recBuff+len, MAX_LEN_TXID);
  tmpStr[MAX_LEN_TXID]='/0';
  len+=MAX_LEN_TXID;
  HexToInt4(tmpStr,tmpInt);
  recMsg.sequence=tmpInt;
  strncpy(tmpStr, recBuff+len, MAX_LEN_TXCTRL);
  tmpStr[MAX_LEN_TXCTRL]='/0';
  len+=MAX_LEN_TXCTRL;
  StrTrim(tmpStr," ");
  for(tmpInt=0;tmpInt<4;tmpInt++) if(strcmp(pTx[tmpInt],tmpStr)==0) break;
  recMsg.txCtrl=tmpInt;
  strncpy(tmpStr, recBuff+len, MAX_LEN_TXRSVD);
  tmpStr[MAX_LEN_TXRSVD]='/0';
  len+=MAX_LEN_TXRSVD;
  //解码操作信息
  tmpInt=msglen-(MAX_HEAD_LEN);
  strncpy(tmpStr, recBuff+len, tmpInt);
  tmpStr[tmpInt]='/0';
  len+=tmpInt;
  StrTrim(tmpStr," ");
  strcpy(recMsg.cmd, tmpStr);
  //解码校验和
 
  strncpy(tmpStr, recBuff+len, MSG_CHKSUM_LEN);
  tmpStr[MSG_CHKSUM_LEN]='/0';
  len=MSG_STARTTAG_LEN + MSG_INFOLEN_LEN;
  GetChkSum(msglen,recBuff+len,chksum);
  if(strncmp(tmpStr,chksum,MSG_CHKSUM_LEN) != 0)
  {
   printf("Msg chksum error.");
   return Failure;
  }
  //解码完毕,打印消息
 
  PrintMsg(recMsg);
  return Success;
}

/*************************发送消息***************************/
int CDeal::SendMsg(int m_sockfd, char* sendBuff)
{
 send(m_sockfd, sendBuff, sizeof(sendBuff), 0);
 return 0;
}


/*************************接收消息**************************/
int CDeal::RecvMsg(int m_sockfd, char* recvBuff)
{
 int recLen = recv( m_sockfd, recvBuff, sizeof(recvBuff),0 );
 if(recLen>0)
 {
 printf("/nreceive login ack message.../n/n");
 //解码消息并获取相应的操作结果
 Decode(recvMsg,recvBuff,recLen,TYPE_OF_CMD_MSG);
 }
 return 0;
}

/*Function: GetChkSum
Description: 实现对"消息头 + 会话头 + 事务头 + 操作信息"按32位异或
 
Calls:
Called By:
Input: len是指"消息头 + 会话头 + 事务头 + 操作信息"四者的长度和。
 
Buf是指"消息头 + 会话头 + 事务头 + 操作信息"四者结合的字符数组。
 
Output: res是指按32位异或得到的结果
Return:
Others:
*************************************************/
void CDeal::GetChkSum(int len, PSTR buf, PSTR res)
{
  memset(res, 0, 4);  //AAA格式的校验码为4字节
  for(int i=0; i<len; i+=4)
  {
   res[0]^=(buf+i)[0];
   res[1]^=(buf+i)[1];
   res[2]^=(buf+i)[2];
   res[3]^=(buf+i)[3];
  }
  res[0]=~res[0];
  res[1]=~res[1];
  res[2]=~res[2];
  res[3]=~res[3];
}

/*********************打印消息******************/
void CDeal::PrintMsg(MsgInfo msg)
{

}


char* CDeal::Int2ToHex(unsigned int _Int2)
{

 char tmp[5];
 char *_hex = new char;
 sprintf(tmp, "%04x", _Int2);
 for(int i=0; i<4; i++)
 {
  sprintf(_hex+sizeof(_hex),"//x%x",tmp[i]);
 }
 return _hex;
}


char* CDeal::Int4ToHex(int _Int4)
{
 char tmp[9];
 char *_hex = new char;
 sprintf(tmp,"%08x", _Int4);
 for(int i=0; i<8; i++)
 {
  sprintf(_hex+i*4, "//x%x", tmp[i]);
 }
 return _hex;
}

void CDeal::HexToInt2(char* _hex, int _Int2)
{
 sscanf(_hex,"%4x", &_Int2);
}


void CDeal::HexToInt4(char* _hex, int _Int4)
{

 sscanf(_hex, "%8x", &_Int4);
}

 

 

 

 

 

 

 

 

 

 

 

// Deal.h: interface for the CDeal class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_DEAL_H__0C860618_5F96_42D5_AD20_C5EA3C0CF0ED__INCLUDED_)
#define AFX_DEAL_H__0C860618_5F96_42D5_AD20_C5EA3C0CF0ED__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000


//宏定义
 
#define MAX_LEN_VERSION        4 
#define MAX_LEN_TERMINAL       8 
#define MAX_LEN_SERVNAME       8  
#define MAX_LEN_DLGCTRL        6 
#define MAX_LEN_TXID           8 
#define MAX_LEN_TXCTRL         6
#define MAX_LEN_TXRSVD         4
#define MAX_MSG_LEN            65536
#define MAX_HEAD_LEN           56
#define MSG_STARTTAG_LEN       4
#define MSG_INFOLEN_LEN        4 
#define MSG_CHKSUM_LEN         4
#define MSG_COMM_LEN           12
#define MAX_HB_MSG_LEN         4 
#define MAX_HB_CONTENT_LEN     4
#define MAX_HB_CHCKSUM         4
#define HB_MSG_LEN             16
#define MAX_LEN_DLGID          8
#define MAX_LEN_DLGRSVD        4
#define MSG_STARTTAG           "/x1C/x1D/x1E/x1F"
#define MSG_VERSION            "1.00"
#define MSG_TERMINAL           "internal"
#define MSG_TXRSVD             "    "
#define MSG_DLGRSVD            "    "
#define HB_CONTENT             "HBHB"
#define Failure       0
#define Success       1
#define NotCMD                 2 
#define TYPE_OF_HB_MSG     1000
#define TYPE_OF_CMD_MSG        1001
struct MsgInfo
{
 char* cmd;
 char* service;
 int snLogin;
 int dlgCtrl;
 int sequence;
 int txCtrl;
};
class CDeal 
{
public:
 CDeal();
 virtual ~CDeal();
public:
 int connectMML(int& m_sockfd, CString& m_ip, int& m_port) ;
 int  Encode(MsgInfo &sendMsg,char* sendBuff, int& sendLen, int send_type);
 int  Decode(MsgInfo &recMsg,char* recBuff,int& recLen, int recv_type);
 int  SendMsg(int m_sockfd, char* sendBuff);
 int  RecvMsg(int m_sockfd, char* recvBuff);
 void PrintMsg(MsgInfo msg);
 void GetChkSum(int len, PSTR buf, PSTR res);
 char* Int2ToHex(unsigned int _Int2);
 char* Int4ToHex(int _Int4);
 void  HexToInt2(char*  _hex, int _Int2);
 void  HexToInt4(char*  _hex, int _Int4);
public:
 MsgInfo recvMsg;
 MsgInfo sendMsg;
};

#endif // !defined(AFX_DEAL_H__0C860618_5F96_42D5_AD20_C5EA3C0CF0ED__INCLUDED_)

 

源码来自:https://pan.quark.cn/s/41b9d28f0d6d 在信息技术领域中,jQuery作为一个广受欢迎的JavaScript框架,显著简化了诸多操作,包括对HTML文档的遍历、事件的管理、动画的设计以及Ajax通信等。 本篇文档将深入阐释如何运用jQuery达成一个图片自动播放的功能,这种效果常用于网站的轮播展示或幻灯片演示,有助于优化用户与页面的互动,使网页呈现更加动态的视觉体验。 为了有效实施这一功能,首先需掌握jQuery的核心操作。 通过$符号作为接口,jQuery能够迅速选取DOM组件,例如$("#id")用于选取具有特定ID的元素,而$(".class")则能选取所有应用了某类class的元素。 在选定元素之后,可以执行多种行为,诸如事件监听、样式的变更、内容的更新以及动画的制作等。 关于“一个基于jQuery的图片自动播放功能”,首要任务是准备一组图片素材,这些素材将被整合至一个容器元素之中。 例如,可以构建一个div元素,将其宽度设定为单张图片的尺寸,再借助CSS实现溢出内容的隐藏,从而构建出水平滚动的初始框架。 ```html<div id="slider"> <img src="image1.jpg" alt="Image 1"> <img src="image2.jpg" alt="Image 2"> <!-- 更多图片内容... --></div>```接着,需要编写jQuery脚本以实现图片的自动切换。 这通常涉及到定时器的运用,以设定周期性间隔自动更换当前显示的图片。 通过使用`.fadeOut()`和`.fadeIn()`方法,能够实现图片间的平滑过渡,增强视觉效果。 ```javascript$(document).re...
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值