模拟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; }
相关文章推荐
- 一个简单的自定义通信协议(socket)
- 使用SuperSocket实现TLV自定义协议网络通信的Demo
- 一个简单的自定义通信协议(socket)
- 使用SuperSocket实现TLV自定义协议网络通信的Demo
- 一个简单的自定义通信协议(socket)
- 一个简单的自定义通信协议(socket)
- 一个简单的自定义通信协议(socket)
- 一个简单的自定义通信协议(socket)
- 一个简单的自定义通信协议(socket)
- 一个简单的自定义通信协议(socket)
- 一个简单的自定义通信协议(socket)
- socket编程里,如何设计自定义通信协议的包头?
- 一个简单的自定义通信协议(socket)
- socket编程里,如何设计自定义通信协议的包头?
- UDP协议模拟计算机通信
- C语言socket模拟客户和服务器通信
- Mina实现自定义协议的通信
- [Android进阶]之深入了解通信协议:http、TCP/IP协议与socket之间的区别
- 使用socketserver模块和socket模块模拟客户端和服务器端通信
- 基于socket简单通信协议实现