發送程序:
//udpsend.cpp
#include <netinet/in.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/file.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/ftp.h>
#include <arpa/inet.h>
#include <arpa/telnet.h>
#include <stdio.h>
#include <signal.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <netdb.h>
//以下是我數據構造所依賴的頭文件
#include "MiniTipsJCE_with_header.h"
#include "video_packet.h"
#include "cs_packet2.h" // for cs packet
#include "jce/Jce.h"
//此處是我所數據構造所依賴的命名空間
using namespace tipsPackage;
int main()
{
char buf[4096];
//buf測試數據d的構造
tipsPackage::tipsRequest stReq;
stReq.header.type = tipsPackage::HeartBeatRequest; //beat
stReq.header.proto_version = 4;
stReq.header.seq = 22222;
stReq.client_version = "4.3";
stReq.uin = 88888888;
stReq.guid = "0";
stReq.tips_key.type = KeyType_QQ;
stReq.tips_key.value = "88888888";
stReq.ack = "1" ;
stReq.report = "just a test" ;
//buf數據部分由自己處理構造,此處只是我的一個構造方式
taf::JceOutputStream<taf::BufferWriter> csStreamOutput;
stReq.writeTo(csStreamOutput);
memcpy(buf, csStreamOutput.getBuffer(), csStreamOutput.getLength());
//要發送的ip和地址
string ip = "10.177.141.106";
int port = 11400;
int socket_cli = socket(AF_INET, SOCK_DGRAM, 0);
struct sockaddr_in address;
bzero(&address, sizeof(address));
address.sin_family = AF_INET;
address.sin_addr.s_addr = inet_addr(ip.c_str());
address.sin_port = htons(port);
//發送
sendto(socket_cli, buf, sizeof(buf), 0, (struct sockaddr*)&address, sizeof(address));
close(socket_cli);
return 0;
}
接收程序:
//udprev.cpp
#include <iostream>
#include <netinet/in.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/file.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/ftp.h>
#include <arpa/inet.h>
#include <arpa/telnet.h>
#include <stdio.h>
#include <signal.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <netdb.h>
// 以下是我數據構造所依賴的頭文件
#include "MiniTipsJCE_with_header.h"
#include "jce/Jce.h"
#include "video_packet.h"
#include "cs_packet2.h" // for cs packet
using namespace std;
//此處是我所數據構造所依賴的命名空間
using namespace tipsPackage;
//輸出
void inputData(tipsBus stRespTransit)
{
cout << "result :" << endl;
cout << "type :" << stRespTransit.type << endl;
cout << "sClientIp :" << stRespTransit.sClientIp << endl;
cout << "iPort :" << stRespTransit.iPort << endl;
cout << "header.type :" << stRespTransit.stData.header.type << endl;
cout << "proto_version :" << stRespTransit.stData.header.proto_version << endl;
cout << "seq :" << stRespTransit.stData.header.seq << endl;
cout << "client_version :" << stRespTransit.stData.client_version << endl;
cout << "uin :" << stRespTransit.stData.uin << endl;
cout << "guid :" << stRespTransit.stData.guid << endl;
cout << "tips_key.type :" << stRespTransit.stData.tips_key.type << endl;
cout << "tips_key.value :" << stRespTransit.stData.tips_key.value << endl;
cout << "ack :" << stRespTransit.stData.ack << endl;
cout << "report :" << stRespTransit.stData.report << endl;
}
//解析數據(對數據的解析由自己構造, 這只是我自己的數據結構)
void handleData(uint8_t *buf, int bufLen)
{
//解析buf
CCsPacket stCsPacket;
stCsPacket.set_packet(buf, bufLen);
if (stCsPacket.decode() != 0)
cout << "cs error" << endl;
//解析cs包
uint8_t *bufCs = (uint8_t *)stCsPacket.getBody();
CVideoPacket stVideoPacket;
stVideoPacket.set_packet(bufCs, stCsPacket.getBodyLen());
if (stVideoPacket.decode() != 0)
cout << "video error" << endl;
//解析video包
char *bufVideo = (char *)stVideoPacket.getBody().data();
taf::JceInputStream<taf::BufferReader> csStreamInput;
csStreamInput.setBuffer(bufVideo, stVideoPacket.getBody().length());
cout << "stVideoPacket.getBody().length(): " << stVideoPacket.getBody().length() ;
//解析jce
tipsBus stRespTransit;
stRespTransit.readFrom(csStreamInput);
//輸出
inputData(stRespTransit);
}
int main()
{
uint8_t buf[4096]; //數據存放
//要發送的ip和地址
string ip = "10.177.141.106";
int port = 22222;
struct sockaddr_in address;
bzero(&address, sizeof(address));
address.sin_family = AF_INET;
address.sin_addr.s_addr = inet_addr(ip.c_str());
address.sin_port = htons(port);
int socket_ser = socket(AF_INET, SOCK_DGRAM, 0);
//綁定,接收此ip地址發來的數據
bind(socket_ser, (struct sockaddr*)&address, sizeof(address));
socklen_t add_len = sizeof(address);
//接收
int iRet = recvfrom(socket_ser, buf, sizeof(buf), 0, (struct sockaddr*)&address, &add_len);
if (iRet > 0)
{
//處理邏輯(如果iRet>0,則表示收到了數據,iRet爲收到的具體長度)
handleData(buf, iRet);
}
close(socket_ser);
return 0;
}
也可以採用下面這種放在一起的
//udpSendAndRev.cpp
#include <netinet/in.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/file.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/ftp.h>
#include <arpa/inet.h>
#include <arpa/telnet.h>
#include <stdio.h>
#include <signal.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <netdb.h>
//以下是我數據構造所依賴的頭文件
#include "jce/Jce.h"
#include "account_inner.h"
#include "video_packet.h"
#include "cs_packet2.h" // for cs packet
//此處是我所數據構造所依賴的命名空間
using namespace VideoAccount;
using namespace std;
//輸出
void inputData(AllocVUidRsp &stResp)
{
cout << "result :" << endl;
cout << "iRet :" << stResp.iRet << endl;
cout << "lVUid :" << stResp.lVUid << endl;
}
//解析數據(對數據的解析由自己構造, 這只是我自己的數據結構)
void handleData(uint8_t *buf, int bufLen)
{
CVideoPacket stVideoPacket;
stVideoPacket.set_packet(buf, bufLen);
if (stVideoPacket.decode() != 0)
cout << "video error" << endl;
//解析video包
char *bufVideo = (char *)stVideoPacket.getBody().data();
taf::JceInputStream<taf::BufferReader> csStreamInput;
csStreamInput.setBuffer(bufVideo, stVideoPacket.getBody().length());
cout << "stVideoPacket.getBody().length(): " << stVideoPacket.getBody().length() ;
//解析jce
AllocVUidRsp stResp;
stResp.readFrom(csStreamInput);
//輸出
inputData(stResp);
}
int main(int argc, char *argv[])
{
char bufSend[4096];
char bufRev[4096];
if (argc < 4)
{
cout << "----------------------------------------------------------------------" << endl;
cout << "there need four argv [./udpsend sendIP sendPORT UIN]" << endl;
cout << "like : ./udpsend 127.0.0.1 22222 569046739" << endl;
cout << "----------------------------------------------------------------------" << endl;
return -1;
}
string strSendIP = argv[1];
string strSendPORT = argv[2];
string strUIN = argv[3];
//buf測試數據d的構造
AllocVUidReq stReq;
stReq.strOutKey = strUIN;
//buf數據部分由自己處理構造,此處只是我的一個構造方式
taf::JceOutputStream<taf::BufferWriter> csStreamOutput;
stReq.writeTo(csStreamOutput);
//add video header
CVideoPacket stVideoPacket;
stVideoPacket.setBody(csStreamOutput.getBuffer(), csStreamOutput.getLength());
stVideoPacket.setCommand(0x111);
stVideoPacket.encode();
//組裝發送數據
memcpy(bufSend, stVideoPacket.getPacket(), stVideoPacket.getPacketLen());
//要發送的ip和地址
string ip = strSendIP;
int port = atoi(strSendPORT.c_str());
int socket_cli = socket(AF_INET, SOCK_DGRAM, 0);
struct sockaddr_in address;
bzero(&address, sizeof(address));
address.sin_family = AF_INET;
address.sin_addr.s_addr = inet_addr(ip.c_str());
address.sin_port = htons(port);
//發送
sendto(socket_cli, bufSend, sizeof(bufSend), 0, (struct sockaddr*)&address, sizeof(address));
//接收
int iRet = recvfrom(socket_cli, bufRev, sizeof(bufRev), 0, NULL, NULL);
if (iRet > 0)
{
//處理邏輯(如果iRet>0,則表示收到了數據,iRet爲收到的具體長度)
handleData((uint8_t *)bufRev, iRet);
}
else
{
cout << "not recv data" << endl;
}
close(socket_cli);
return 0;
}
收發函數:
int recvfrom(SOCKET s,void *buf,int len,unsigned int flags, struct sockaddr *from,int *fromlen);
int sendto(SOCKET s, const char * buf, int len, int flags, const struct sockaddr *to, int tolen);
s:一個標識套接口的描述字。
buf:包含待發送數據的緩衝區。
len:buf緩衝區中數據的長度。
flags:調用方式標誌位。
to:(可選)指針,指向目的套接口的地址。
tolen:to所指地址的長度。