自定义协议(客户端)

协议文件定义,头文件

#pragma  once
//
//  constants define
//
#define SOCKETCREATEFAIL         -1
#define SOCKETBINDFAIL           -2
#define SOCKETIOCTLFAIL          -3
#define SOCKETSETLECTFAIL        -4
#define SOCKETCONETCFAIL         -5
//
// struct define
//
typedef struct {
 unsigned char SystemID;
 unsigned char NULL1;
 unsigned char headerlength;
 unsigned char IDopCode;
 unsigned char OpCodelength;
 unsigned char OpCode;
    unsigned char ORGField;
 unsigned char ORGfieldlength;
 unsigned char ORGID;
 unsigned char DBNR;
 unsigned char HighofStartAddress;
 unsigned char LowofStartAddress;
 unsigned char HighofLength;
 unsigned char LowofLength;
 unsigned char EmptyField;
 unsigned char LengthofEmptyField;
 unsigned char Data;
}StructReqFrame;
typedef struct  {
 int Area;
 int DBNR;
 int StartAddress;
 int Length;
}StructPLCAddr;
//
//  function header 
//
void Log(char *LogFileDirectory ,char pData[4096], int len, int nDatatype);
int CreateTCPSocket(struct sockaddr_in *socketAddr);

协议文件CPP

#include <StdAfx.h>
#include "DrvProtocol .h"
#include <windows.h>
#include <time.h>
#include <locale.h>
#include <stdio.h>
#include <WINSOCK2.H>
extern char  szDllPath[80];
void Log(char *LogFileDirectory ,char pData[4096], int len, int nDatatype)
{ 
 SYSTEMTIME st;
 setlocale(LC_ALL, "");
 GetLocalTime(&st); 
 char *sPath   = new char[256];
 char *sFile   = new char[256];
 char *sWrite  = new char[5000];
 memset(sWrite, 0, 5000);
 memset(sPath, 0, 256);
 strcpy(sPath, LogFileDirectory) ;
    memset(sFile, 0, 256);
 sprintf(sFile, "%d%02d%02d%02d.log", st.wYear, st.wMonth, st.wDay, st.wHour);
    sprintf(sPath, "%s\\%s", LogFileDirectory, sFile);
    
 sprintf(sWrite, "%02d:%02d:%02d ", st.wHour, st.wMinute, st.wSecond);
 switch(nDatatype)
 {
 case 1:
  strcat(sWrite,"发送:");
  break;
 case 2:
  strcat(sWrite,"接收:");
  break;
 default:
  strcat(sWrite,"消息:");
  break;
 }
 
 if(nDatatype == 1 || nDatatype == 2)
 {
  for (int i=0; i<len; i++)
  {
   char temp[20];
   memset(temp, 0, 20);
   sprintf(temp, "%02X ", pData[i]);
   if( pData[i] & 0x80) 
   {
    strcat(sWrite, temp + 6);
   }
   else strcat(sWrite, temp);
  }
 }
    else
    strcat(sWrite,pData);
 strcat(sWrite, "\r");
 strcat(sWrite, "\n"); 
 FILE *pFile;
    pFile = fopen(sPath, "at+"); 
 if (pFile != NULL)
 {
  fputs(sWrite, pFile);
  fclose(pFile);
 }
 delete sFile;
 delete sWrite;
 delete sPath;
}
int CreateTCPSocket(struct sockaddr_in *socketAddr)
{
 int ret;
    int nsocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
 if (nsocket == INVALID_SOCKET)
 {
  printf("socket() failed!\n");
  return SOCKETCREATEFAIL;
 }
 
 ret = connect(nsocket, (struct sockaddr *)socketAddr, sizeof(*socketAddr));
 if (ret == SOCKET_ERROR)
 {
  printf("connect() failed!\n");
  closesocket(nsocket); 
  return SOCKETCONETCFAIL;
 }
// unsigned  long   ul = 1; 
// ret = ioctlsocket(nsocket,FIONBIO,(unsigned long*)&ul); 
// if(ret==SOCKET_ERROR)
// {
//  closesocket(nsocket);
//  Log(szDllPath,"ioctlsocket socket fail",22,3);
//  WSACleanup();  
//  return SOCKETIOCTLFAIL;
// }
 return nsocket;  
}

调用CPP

// CPReadWrite.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <stdlib.h>
#include "DrvProtocol .h"
#include <winsock.h>
#pragma comment(lib,"Ws2_32")
char          szDllPath[80];
WORD          wCommand = 1;
char *pCharData;
int PlcAddrConfig(char * strConfigFile, StructPLCAddr * &plcAddr,char * &pCh)
{
 int  nret = -1;
 int  ntmp =  0;
 int  ntotal;
 char strBuffer[64];
 int  nAddrtotallLength = 0;
 ntotal = GetPrivateProfileInt("PLCDATA","TOTALDATA",-1,strConfigFile);
 if(- 1 == ntotal) return -1;
 plcAddr = new StructPLCAddr[ntotal + 1];
 memset(plcAddr,0,sizeof(StructPLCAddr) * (ntotal + 1));
 while(nret)
 {
  char* pChr,*pNchr;
  memset(strBuffer,0,64);
  nret = GetPrivateProfileString("PLCDATA",NULL,"",strBuffer,sizeof(strBuffer),strConfigFile); 
  printf("KeyName:%s",strBuffer);
  nret = GetPrivateProfileString("PLCDATA",strBuffer,"",strBuffer,sizeof(strBuffer),strConfigFile); 
  printf("Value:%s\n",strBuffer);
  pChr = strBuffer;
  pNchr = strchr(pChr,‘|‘);
  plcAddr[ntmp].Area = atoi(strstr(pChr,pNchr));
  pChr = pNchr;
  pNchr = strchr(pChr,‘|‘);
  plcAddr[ntmp].DBNR = atoi(strstr(pChr,pNchr));
  pChr = pNchr;
  pNchr = strchr(pChr,‘|‘);
  plcAddr[ntmp].StartAddress = atoi(strstr(pChr,pNchr));
  pChr = pNchr;
   
  pNchr = strchr(pChr,‘|‘);
  plcAddr[ntmp].Length = atoi(strstr(pChr,pNchr));
  pChr = pNchr;
  nAddrtotallLength += plcAddr[ntmp].Length;
  if(++ntmp = ntotal)
  {
   break;
  }
 }
 if(!nret)
 {
  Log(szDllPath,"the configure TOTALDATA > PLCDATA number",45,3);
 }
 pCh = new char[ntmp];
 memset(pCh,0,ntmp);
 return 0;
}
void main(int argc, char* argv[])
{
 char *strIniFile = ".\\SiemensCP.ini";
 StructPLCAddr *pPlcAddre;
 StructPLCAddr *t_pPlcAddre;
 StructReqFrame ReqFrame;
    char *t_pCharData;
    PlcAddrConfig(strIniFile,pPlcAddre,pCharData);
    t_pPlcAddre = pPlcAddre;
 t_pCharData  = pCharData;
 SOCKET socket_Fetch = 0;
 SOCKET socket_Write = 0;
    sockaddr_in socketAddr;
 char *chipAddress = new char[40];
 char *socketBuff = new char[2049];
    WORD ret = 0;
    strcpy(szDllPath,"D:\\"); 
 memset(chipAddress,0,40);
 memset(socketBuff,0,2049);
 ReqFrame.SystemID      =  0x53; 
 ReqFrame.NULL1         =  0x35;
 ReqFrame.headerlength  =  0x10;
 ReqFrame.IDopCode      =  0x01;
 ReqFrame.OpCodelength  =  0x03;
    ReqFrame.ORGField      =  0x03;
 ReqFrame.ORGfieldlength=  0x08; 
    int nPort;
 WSADATA wsaData;
 ret = WSAStartup(MAKEWORD(2, 2), &wsaData); 
    if(ret!=0)  
 {  
  WSACleanup();  
  return ;  
 }
 if(LOBYTE(wsaData.wVersion)!=2 || HIBYTE(wsaData.wVersion)!=2)
 {
  WSACleanup(); 
  printf("Invalid WinSock version!\n");
  return ;
 }
 
 socketAddr.sin_family = AF_INET;
 GetPrivateProfileString("SIEMENSCP","FETCHIP",NULL,chipAddress,40,strIniFile);
 nPort      = GetPrivateProfileInt("SIEMENSCP","FETCHPORT",NULL,strIniFile);
    socketAddr.sin_port = htons(nPort); 
 socketAddr.sin_addr.S_un.S_addr = inet_addr(chipAddress);
 Log(szDllPath,"Fetch ip:",9,3);
    Log(szDllPath,chipAddress,20,3);
 socket_Fetch = CreateTCPSocket(&socketAddr);
 GetPrivateProfileString("SIEMENSCP","WRITEIP ",NULL,chipAddress,40,strIniFile);
    nPort          = GetPrivateProfileInt("SIEMENSCP","WRITEPORT",NULL,strIniFile);
 socketAddr.sin_port = htons(nPort); 
    socketAddr.sin_addr.S_un.S_addr = inet_addr(chipAddress);
 Log(szDllPath,"Write ip:",9,3);
    Log(szDllPath,chipAddress,20,3);     
 socket_Write   = CreateTCPSocket(&socketAddr);
  
    while(socket_Fetch  > 0 && socket_Write > 0)
 {   
  ReqFrame.EmptyField         =  (char)0XFF;
     ReqFrame.LengthofEmptyField =  0x02;
        if(0 == wCommand) break;
  switch(wCommand)
  {
  case 1:
   ReqFrame.OpCode             =  0x05;  
   Log(szDllPath,(char*)&ReqFrame,16,1);
   memcpy(socketBuff,&ReqFrame,16);
   while(pPlcAddre->Area)
   {
    send(socket_Fetch,socketBuff,16,0);
    memset(socketBuff,0,2049);
    recv(socket_Fetch,socketBuff,2048,0);
       strcpy(t_pCharData,(socketBuff + pPlcAddre->Length + 1));
    t_pCharData += pPlcAddre->Length;
    pPlcAddre++;
   }  
         Log(szDllPath,socketBuff,17 + (int)ReqFrame.LowofLength + (int)ReqFrame.HighofLength,2);
   break;
  case 2:
   ReqFrame.OpCode             =  0x03;
   memcpy(socketBuff,&ReqFrame,17);
   Log(szDllPath,(char*)&ReqFrame,16 + (int)ReqFrame.LowofLength +  (int)ReqFrame.HighofLength,1);
   send(socket_Write,socketBuff,16 + (int)ReqFrame.LowofLength +  (int)ReqFrame.HighofLength,0);
    memset(socketBuff,0,2049);
    do
    {
     recv(socket_Write,socketBuff,2048,0);
    }while(NULL == *socketBuff);
         Log(szDllPath,socketBuff,16,2);
   break;
  default:
   break;
  }
 }
 delete chipAddress;
 delete socketBuff;
 delete pPlcAddre;
 delete pCharData;
 closesocket(socket_Fetch);
 closesocket(socket_Write);
 Log(szDllPath,"PLC thread exit",16,3);
 WSACleanup(); 
 return ;
}

配置文件

[SIEMENSCP]
DEBUG         = 1
FETCHIP       = 172.30.0.204
FETCHPORT     = 2000
WRITEIP       = 172.30.0.204
WRITEPORT     = 2001
TOTALLENGTH   = 250
[PLCDATA]
1 = 区|开始地址|长度
2 = 区|开始地址|长度
3 = 区|开始地址|长度
4 = 区|开始地址|长度
                       ;01   = 0X0000 -- 0XEFFF       ;栈 0 - 15 板 0 - 15
                       ;02   = 0XF000 -- 0XF1FF       ;栈 16     板 1       通道 0   - 127 
                       ;03   = 0XF200 -- 0XF28F       ;栈 16     板 2       通道 0   - 127 
                       ;04   = 0XF290 -- 0XF2FF       ;栈 16     板 2       通道 128 - 255
                       ;05   = 0XF300 -- 0XF3FF       ;栈 16     板 3       通道 0   - 255
                       ;06   = 0XF400 -- 0XF4FF       ;栈 16     板 4       通道 0   - 255
                       ;07   = 0XF500 -- 0XF5FF       ;栈 16     板 5       通道 0   - 255
时间: 2024-11-08 03:52:55

自定义协议(客户端)的相关文章

第13章 TCP编程(3)_基于自定义协议的多进程模型

5. 自定义协议编程 (1)自定义协议:MSG //自定义的协议(TLV:Type length Value) typedef struct{ //协议头部 char head[10];//TLV中的T unsigned int checkNum; //校验码 unsigned int cbSizeContent; //协议体的长度 //协议体部 char buff[512]; //数据 }MSG; (2)自定义读写函数 ①extern int write_msg(int sockfd, cha

Netty 5 自定义协议 教程

网上好多连接好多demo都不是netty5的,都是以前的版本,况且还有好多运行时老报错.入门级demo就不写了,估计都是那些老套路.好多公司都会有最佳实践,今天就说说如何自定义协议,一般自定义协议都是公司内部各个部门定义的,当然了我写的比较简单. 注意: 本教程是采用netty-all-5.0.0.Alpha2.jar,netty5的版本,不是网上很多的例子都是采用以前老大版本. 自定义协议: 协议 {   协议头(header)   消息体(body) } header格式 {   固定头,

第13章 TCP编程(4)_基于自定义协议的多线程模型

7. 基于自定义协议的多线程模型 (1)服务端编程 ①主线程负责调用accept与客户端连接 ②当接受客户端连接后,创建子线程来服务客户端,以处理多客户端的并发访问. ③服务端接到的客户端信息后,回显给客户端 (2)客户端编程 ①从键盘输入信息,并发送给服务端 ②接收来自服务端的信息 //msg.h与前一节相同 #ifndef __MSG_H__ #define __MSG_H__ #include <sys/types.h> //求结构体中成员变量的偏移地址 #define OFFSET(T

C#综合揭秘——通过修改注册表建立Windows自定义协议

引言 本文主要介绍注册表的概念与其相关根项的功能,以及浏览器如何通过连接调用自定义协议并与客户端进行数据通信.文中讲及如何通过C#程序.手动修改.安装项目等不同方式对注册表进行修改.其中通过安装项目对注册表进行修改的情况最为常见,在一般的应用程序中都会涉及.当中最为实用的例子将介绍如何通过"安装项目"修改注册表建立自定义协议,在页面通过ajax方式发送路径请求,并在回调函数中调用自定义协议.最后一节还将介绍如何调用自定义协议去保持数据的保密性.希望本篇文章能对各位的学习研究有所帮助,当

wireshark插件开发 - 自定义协议

虽然wireshark自带了很多知名协议的解析插件,譬如HTTP.DHCP等等,然而在实际应用环境中,有不少软件之间的通信协议都是私有的,如游戏客户端和服务器之间的交互协议通常都是私有的,wireshark无法具体解析出各种字段之间的含义,只能显示接收到的二进制数据,给协议的分析和问题的排查带来了一定的困难,尤其是协议内容比较复杂时. 本文一个自定义的简单协议入手,分析如何基于wireshark开发自定义协议分析插件. 1.1. 概述 本书使用Go语言来描述协议的交互过程.Go由Google出品

【Win10 UWP】URI Scheme(二):自定义协议的处理和适用场景

上一篇提到Windows Store协议的使用,其实Windows Store协议仅是系统内建的一种协议规则.我们也可以自己定义一套规范的URI-Scheme,除了可以给其他App调用外,本应用也可以进行调用,解决一些特殊的场景,本讲具体探讨这一问题. 关于Windows Store协议的解析和使用,可先阅读上一篇:http://www.cnblogs.com/zhxilin/p/4819372.html 一.自定义协议的处理 前面提到,通过协议,应用可以被“激活(Activated)”,并且可

Netty自定义协议解析原理与应用

目前,大家都选择Netty做为游戏服务器框架网络通信的框架,而且目前也有很多优秀的产品是基于Netty开发的.它的稳定性,易用性和高效率性已得到广泛的认同.在游戏服务器开发中,选择netty一般就意味着我们要使用长连接来建立与客户端的通信,并且是自定义协议,在网络开发中,我们不得不处理断包,粘包的问题,因为Tcp/ip是基于数据流的传输,包与包之间没有明确的界限,而且于由网络路由的复杂性,大包有可能分成小包,小包也有可能被组装成大包进行传输.而Netty就考虑到了这一点,而且它用一个类就帮我们处

mina的编码和解码以及断包的处理,发送自定义协议,仿qq聊天,发送xml或json和

最近一段时间以来,mina很火,和移动开发一样,异常的火爆.前面写了几篇移动开发的文章,都还不错,你们的鼓励就是我最大的动力.好了,废话少说.我们来看下tcp通讯吧. tcp通讯对于java来说是很简单的.就是socket,也就是大家常说的套接字.大家不要把它看的很难.说白了tcp通讯其实就是数据流的读写.一条输入流,一条输出流.分别复杂发消息和接收消息. 明白了这些,ok,我们来看看我写的例子吧.先看服务器端的测试类的源码: package com.minaqq.test; import co

【转】C#综合揭秘——通过修改注册表建立Windows自定义协议

引言 本文主要介绍注册表的概念与其相关根项的功能,以及浏览器如何通过连接调用自定义协议并与客户端进行数据通信.文中讲及如何通过C#程序.手动修改.安装项目等不同方式对注册表进行修改.其中通过安装项目对注册表进行修改的情况最为常见,在一般的应用程序中都会涉及.当中最为实用的例子将介绍如何通过"安装项目"修改注册表建立自定义协议,在页面通过ajax方式发送路径请求,并在回调函数中调用自定义协议.最后一节还将介绍如何调用自定义协议去保持数据的保密性.希望本篇文章能对各位的学习研究有所帮助,当

swoole入门教程05-Swoole的自定义协议功能的使用

环境说明: 系统:Ubuntu14.04 (安装教程包括CentOS6.5) PHP版本:PHP-5.5.10 swoole版本:1.7.8-alpha 1.为什么要提供自定义协议 熟悉TCP通信的朋友都会知道,TCP是一个流式协议.客户端向服务器发送的一段数据,可能并不会被服务器一次就完整的收到;客户端向服务器发送的多段数据,可能服务器一次就收到了全部的数据.而实际应用中,我们希望在服务器端能一次接收一段完整的数据,不多也不少.传统的TCP服务器中,往往需要由程序员维护一个缓存区,先将读到的数