#include "tcpclient.h"
struct user_info{
int code = 0;
union
{
int len = 0;
char strlen[4];
} per_data;
char *data = nullptr;
string fileName;
uint32_t len = 0;//文件总长度
uint32_t curlen =0;//已经接收的长度
FILE *fp = nullptr;//追加
};
string presJson1(int msg,int len,int code,const char* fileName){
StringBuffer s;
Writer<StringBuffer> writer(s);
writer.StartObject();
writer.Key("Msg");
writer.Uint(msg);
writer.Key("len");
writer.Uint(len);
writer.Key("code");
writer.Uint(code);
writer.Key("fileName");
writer.String(fileName);
writer.EndObject();
// qDebug()<<"Client发送数据:"<<s.GetString();
return s.GetString();
}
void handle_sum_call(struct mg_connection *nc, int ev, void *ev_data) {
struct mbuf *io = &nc->recv_mbuf;
user_info *uinfo=(user_info*)nc->user_data;
int len =uinfo->len-uinfo->curlen;//剩下长度
if(len > io->len){
fwrite(io->buf,1,io->len,uinfo->fp);
uinfo->curlen +=io->len;
mbuf_remove(io, io->len);
}else{
fwrite(io->buf,1,len,uinfo->fp);
uinfo->curlen += len;
fclose(uinfo->fp);
uinfo->fp = nullptr;
mbuf_remove(io, len);
uinfo->len =0;
uinfo->curlen =0;
qDebug()<<"文件 "<<uinfo->fileName.c_str()<<" 接收完毕";
uinfo->code = 0;//接收完毕
}
}
void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
struct mbuf *io = &nc->recv_mbuf;
switch (ev) {
case MG_EV_CONNECT:
{
string str=presJson1(0,0,0,"");
int len = str.length();
mg_send(nc, &len, 4);
mg_send(nc, str.c_str(), str.length());
user_info *uinfo = new user_info;
nc->user_data = uinfo;
break;
}
case MG_EV_RECV:
{
struct user_info *uinfo=(user_info*)nc->user_data;
if(uinfo->code == 0){
//接收长度
memcpy(uinfo->per_data.strlen,io->buf,4);
mbuf_remove(io, 4);
if(io->len >=uinfo->per_data.len){
string json(io->buf,uinfo->per_data.len);
//qDebug()<<io->len<<" Client收到数据:|"<<json.c_str()<<"|";
uinfo->code =QJson::GetInt(json.c_str(),"code");
uinfo->len =QJson::GetInt(json.c_str(),"len");
//解析文件名
string fileName=QJson::GetKey(json.c_str(),"fileName").toString().toStdString();
printf("%s\n",fileName.c_str());
uinfo->fileName=fileName;
if(uinfo->code == 1){
uinfo->fp = fopen(fileName.c_str(),"wb");
}
int Msg =QJson::GetInt(json.c_str(),"Msg");
mbuf_remove(io, uinfo->per_data.len);
}
}else if(uinfo->code == 1){
//下载文件
handle_sum_call(nc,ev,ev_data);
}
if(redySend > 0){
mg_send(nc, tcpClient->sendStr.c_str(),tcpClient->sendStr.length());
qDebug()<<"发送数据:"<<tcpClient->sendStr.c_str();
redySend--;
}else{
string str =presJson1(0,0,0,"");
int len = str.length();
mg_send(nc, &len, 4);
mg_send(nc, str.c_str(), str.length());
}
break;
}
case MG_EV_SEND:break;
case MG_EV_CLOSE:
{
if (isRun) {
string url("tcp://");
url.append(inet_ntoa(nc->sa.sin.sin_addr));
url.append(":");
url.append(to_string(ntohs(nc->sa.sin.sin_port)));
// qDebug()<<"断线重连 "<<url.c_str();
mg_connect(nc->mgr,url.c_str(), TCPClient::ev_handler);
}else{
nc->flags |= MG_F_SEND_AND_CLOSE;
delete nc->user_data;
}
break;
}
}
}
void main(){
mg_mgr_init(&mgr, nullptr);
mg_connect(&mgr,url.c_str(), TCPClient::ev_handler);
while(1){
mg_mgr_poll(&mgr, 1);
}
mg_mgr_free(&mgr);
}
其中用到了QT的json解析器 和
rapidjson 封装json
rapidjson 解析有点问题