您的位置:首页 > 其它

模拟socket通信中自定义协议通信(编码/解码、成帧/界定帧)

2012-02-21 19:42 316 查看
头文件

#include <iostream>
#include <stdio.h>
#include <string>
#include <Windows.h>
#include "winsock.h"
#pragma comment(lib, "wsock32")

using namespace std;
//通信消息/命令格式
struct VoteInfo
{
UINT64 count;
int candidate;
bool isInquiry;
bool isResponse;
};
int GetNextMsg(FILE *in, UINT8 *buf, size_t bufSize);
int PutMsg(UINT8 buf[], size_t msgSize, FILE *out);
size_t Encode(const VoteInfo *v, UINT8 *outBuf, const size_t bufSize);
bool Decode(UINT8 *inBuf, const size_t mSize, VoteInfo *v);


源文件:

#include "main.h"

static const char DELIMITER = '\n';

int GetNextMsg(FILE *in, UINT8 *buf, size_t bufSize)
{
int count = 0;
int nextChar;
while (count < bufSize)
{
fseek(in,0,SEEK_CUR);
nextChar = fgetc(in);

//模拟流的取出,一旦输出就不在保留了
//这样取完后,文件中就没有内容了
fseek(in,-1L,SEEK_CUR);
fputc(' ',in);
//fseek(in,1L,SEEK_CUR);

if (nextChar == EOF)
{
if(count > 0){
printf("%s\n","Stream ended prematurely");
return 0;
}
else
return -1;
}
if(nextChar == DELIMITER)
break;
buf[count++] = nextChar;
}
if(nextChar != DELIMITER)
return -count;
else
return count;
}

int PutMsg(UINT8 buf[], size_t msgSize, FILE *out)
{
int i;
for (i=0; i<msgSize; i++)
if(buf[i] == DELIMITER)
return -1;

if (fwrite(buf,1,msgSize,out) != msgSize)
return -1;

fputc(DELIMITER,out);
fflush(out);
return msgSize;
}

static const char *MAGIC = "Voting";
static const char *VOTESTR = "v";
static const char *INQSTR = "i";
static const char *RESPONSESTR ="R";
static const char *DELIMSTR = " ";
enum{
BASE = 10
};

size_t Encode(const VoteInfo *v, UINT8 *outBuf, const size_t bufSize)
{
UINT8 *bufPtr = outBuf;
long size = (size_t)bufSize;

int rv = _snprintf((char *)bufPtr,size,"%s %c %s %d ",MAGIC,(v->isInquiry ? 'i':'v'),
(v->isResponse ? "R":" "),v->candidate);

bufPtr += rv;
size -= rv;
if(v->isResponse){
rv = _snprintf((char *)bufPtr,size, "%llu",v->count);
bufPtr += rv;
}
return (size_t)(bufPtr - outBuf);
}

bool Decode(UINT8 *inBuf, const size_t mSize, VoteInfo *v)
{
char *token;
token = strtok((char *)inBuf,DELIMSTR);
if (token == NULL || strcmp(token,MAGIC) != 0)
return false;

token = strtok(NULL,DELIMSTR);
if(token == NULL)
return false;
if(strcmp(token,VOTESTR) == 0)
v->isInquiry = false;
else if(strcmp(token,INQSTR) == 0)
v->isInquiry = true;
else
return false;

token = strtok(NULL,DELIMSTR);
if(token == NULL)
return false;
if(strcmp(token,RESPONSESTR) == 0)
{
v->isResponse = true;
token = strtok(NULL,DELIMSTR);
if(token == NULL)
return false;
}
else
{
v->isResponse = false;
}

v->candidate = atoi(token);
if(v->isResponse)
{
token = strtok(NULL,DELIMSTR);
if(token == NULL)
return false;
v->count = strtol(token,NULL,BASE);
}
else
{
v->count = 0L;
}
return true;
}

int main()
{
VoteInfo vi;
memset(&vi,0,sizeof(vi));
vi.isInquiry = true;
vi.candidate = 100;
vi.isResponse = true;
vi.count = 1000;

cout << "----------Encoding--------------" << endl;
UINT8 outBuf[500];
size_t reqSize = Encode(&vi,outBuf,500);
cout << reqSize << endl;
cout << outBuf << endl;
cout << endl;

cout << "----------PutMessage------------" << endl;
FILE *sendMsg = fopen("msg.txt","w+");
bool suc = PutMsg(outBuf,reqSize,sendMsg);
cout << suc << endl;
suc = PutMsg(outBuf,reqSize,sendMsg);
cout << suc << endl;
cout << endl;
fclose(sendMsg);

VoteInfo vRecv;
memset(&vRecv,0,sizeof(vRecv));
UINT8 inbuf[500];
memset(inbuf,0,sizeof(inbuf));

cout << "----------ReceiveMessage---------" << endl;
FILE *recvMsg = fopen("msg.txt","r+");
size_t respSize = GetNextMsg(recvMsg,inbuf,500);
cout << respSize << endl;
cout << inbuf << endl;
fclose(recvMsg);

cout << "----------Decoding--------------" << endl;
Decode(inbuf,1,&vRecv);
cout << vRecv.isInquiry << endl;
cout << vRecv.count << endl;
cout << vRecv.isResponse << endl;
cout << vRecv.candidate << endl;
cout << endl;

cout << "----------ReceiveMessage---------" << endl;
recvMsg = fopen("msg.txt","r+");
respSize = GetNextMsg(recvMsg,inbuf,500);
cout << respSize << endl;
cout << inbuf << endl;
fclose(recvMsg);

cout << "----------Decoding--------------" << endl;
Decode(inbuf,1,&vRecv);
cout << vRecv.isInquiry << endl;
cout << vRecv.count << endl;
cout << vRecv.isResponse << endl;
cout << vRecv.candidate << endl;
cout << endl;

cout << "----------ReceiveMessage---------" << endl;
recvMsg = fopen("msg.txt","r+");
respSize = GetNextMsg(recvMsg,inbuf,500);
cout << respSize << endl;
cout << inbuf << endl;
cout << endl;
fclose(recvMsg);

cout << "----------Decoding--------------" << endl;
Decode(inbuf,1,&vRecv);
cout << vRecv.isInquiry << endl;
cout << vRecv.count << endl;
cout << vRecv.isResponse << endl;
cout << vRecv.candidate << endl;
cout << endl;

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: