首页 > 代码库 > 用libevent实现的发送图片

用libevent实现的发送图片

服务器端的代码:

#include <event2/event.h>

#include <event2/event_compat.h>
#include <event2/event_struct.h>
#include <map>
#include <vector>
#include <string>
#include <iostream>
#ifndef _WIN32
#include <fcntl.h>
#include <netinet/in.h>
#include <unistd.h>
#include <sys/socket.h>
else
#include <winsock2.h>
#include <windows.h>
#include <ioctlsocket.h>
#endif
#include <fstream>
#include "include/json/json.h"
#ifdef _WIN32
#pragma comment(lib,"WS2_32")
#endif
//#include <iostream>
#pragma comment(lib,"json_vc71_libmtd.lib")
#pragma comment(lib,"libevent.lib")
#pragma comment(lib,"libevent_core.lib")
#pragma comment(lib,"libevent_extras.lib")
#include "base64.h"
#define SERVER_PORT 55555
//#define MESSAGE_SIZE 64000


struct client {
        struct event ev_read;
};
void on_read(int fd,short ev,void *arg)
{
struct client* client = (struct client*)arg;
std::ifstream file;
file.open("C:/Users/Administrator/Desktop/2.jpg",std::ios_base::in|std::ios_base::binary|std::ios_base::ate);
file.seekg(0,std::ios::end);
char *buffer ;
long size;
size = file.tellg();
buffer = new char [size];
file.seekg(0,std::ios::beg);
file.read (buffer, size);
//std::string pic = buffer;
//std::cout<<pic<<std::endl;
   // std::string picture = base64_encode(reinterpret_cast<const unsigned char*>(pic.c_str()), pic.length());
std::string picture = base64_encode(reinterpret_cast<const unsigned char*>(buffer), size);
//std::cout<<picture<<std::endl;

char des[] ="C:/Users/Administrator/Desktop/2.jpg";
char ch = ‘.‘;
std::string str("C:/Users/Administrator/Desktop/2.jpg");
int index=  str.find(ch);
//std::cout<<index<<std::endl;
int length = sizeof(des)-index;
//std::cout<<length<<std::endl;
std::string format = str.substr(index);
//std::cout<<formal<<std::endl;
char sizeStr[9] ;
sprintf(sizeStr,"%d",size);


Json::Value data;
data["content"] = Json::Value(picture);
//data["content"] = Json::Value(buffer);
data["format"] = Json::Value(format);
data["size"] = Json::Value(sizeStr);
Json::FastWriter fast_writer;
    std::string res = fast_writer.write(data);
    //std::cout<<res<<std::endl;

const char* sbuffer = res.c_str();

int n,nwrite;
long data_size = strlen(sbuffer);
  // char*  data_pointer =0;
//int data_array[]={data_size};
//sprintf(data_pointer,"%d",data_size);
//char* data_array=0;
//itoa(data_size,data_array,10);
send(fd,(char*)&data_size,8,0);
std::cout<<data_size<<std::endl;
n = data_size;
while(n>0)
{
nwrite = send(fd,sbuffer+data_size-n,n,0);
if(nwrite < n)
{
/*if(nwrite == -1 && errno != EAGAIN)
{
    perror("write error");
}*/
break;
}
n -= nwrite;
}
event_del((struct event*)arg);
closesocket(fd);
/*char world[8] = {0};
recv(fd,world,7,0);
std::cout<<world<<std::endl;*/
 delete[]  buffer;
// printf("%s\n",buf);
  
}
//int
//setnonblock(int fd)
//{
//        int flags;
//
//        flags = fcntl(fd, F_GETFL);
//        if (flags < 0)
//                return flags;
//        flags |= O_NONBLOCK;
//        if (fcntl(fd, F_SETFL, flags) < 0)
//                return -1;
//
//        return 0;
//}
void on_accept(int fd,short ev,void *arg)
{
//printf("jump right!");
int conn_fd;
struct sockaddr_in client_addr;
int client_len = sizeof(client_addr);
struct client *client;
//struct event ev_client;
//接受新的连接
conn_fd = accept(fd,(struct sockaddr*)&client_addr,&client_len);
if (conn_fd == -1)
printf("accept failed!");
client = (struct client*)calloc(1,sizeof(*client));
//client = malloc(sizeof(*client));
if(client == NULL)
printf("malloc failed!");
//
std::cout<<"accept connection"<<std::endl;
//printf(client_fd);
event_set(&client->ev_read,conn_fd,EV_READ|EV_WRITE|EV_PERSIST,on_read,client);
event_add(&client->ev_read,NULL);
printf("accepted connection from %s/n",inet_ntoa(client_addr.sin_addr));
}
void init()
{
WSADATA wsa={0};
    WSAStartup(MAKEWORD(2,2),&wsa);
}
void setsocket(int fd,int reuse)
{
/*int listen_fd = fd;
int reuseaddr_on = reuse;
if(setsockopt(listen_fd,SOL_SOCKET,SO_REUSEADDR,&reuseaddr_on,sizeof(reuseaddr_on)) == -1)
printf("setsockopt failed");*/
}
#ifdef _Win32
void address(struct sockaddr_in listen_addr)
{
memset(&listen_addr,0,sizeof(listen_addr));
listen_addr.sin_family= AF_INET;
listen_addr.sin_addr.S_un.S_addr=INADDR_ANY;
listen_addr.sin_port = htons(SERVER_PORT);
}
#endif


int main()
{
 /*   #ifdef _Win32
init();
#endif*/
init();
int listen_fd;
struct sockaddr_in listen_addr;
int reuseaddr_on = 1;
//接受连接请求的事件对象
struct event ev_accept;
    // 初始化libevent
    event_init();
listen_fd = socket(AF_INET,SOCK_STREAM,0);
#ifdef _Win32
int nRet;
nRet = ioctlsocket(listen_fd,FIONBIO,&reuseaddr_on);
if(nRet == SOCKET_ERROR)
{
printf("setNonblock error!");
}
#endif
if(listen_fd < 0)
printf("create failed!");
#ifndef _Win32
setsocket(listen_fd,reuseaddr_on);
#else

#endif
#ifndef _Win32
memset(&listen_addr,0,sizeof(listen_addr));
listen_addr.sin_family=AF_INET;
//listen_addr.sin_addr.s_addr= inet_addr("192.168.11.206");
listen_addr.sin_addr.s_addr= INADDR_ANY;
listen_addr.sin_port=htons(SERVER_PORT);
#else
address(listen_adddr);
#endif
/*memset(&listen_addr,0,sizeof(listen_addr));
listen_addr.sin_family= AF_INET;
listen_addr.sin_addr.S_un.S_addr=INADDR_ANY;
listen_addr.sin_port = htons(SERVER_PORT);*/
if(bind(listen_fd,(struct sockaddr*)&listen_addr,sizeof(listen_addr))<0)
printf("bind failed!");


if(listen(listen_fd,5)<0)
printf("failed to listen!");
event_set(&ev_accept,listen_fd,EV_READ|EV_WRITE|EV_PERSIST,on_accept,NULL);
event_add(&ev_accept,NULL);
    // 事件循环
    event_dispatch();
WSACleanup();
    return 0;

}

客户端接收代码:采用json格式   进行base64编码

#include "client.h"
#include "callBack.h"
void client::initSocket()
{
WSADATA wsa={0};
    WSAStartup(MAKEWORD(2,2),&wsa);
}
int client::conne(void (*)(int))
{
int client_fd;
struct sockaddr_in client_addr;
client_fd = socket(AF_INET,SOCK_STREAM,0);
if(client_fd < 0)
printf("create failed!");
memset(&client_addr,0,sizeof(client_addr));
client_addr.sin_family= AF_INET;
//client_addr.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
client_addr.sin_addr.S_un.S_addr=inet_addr("192.168.11.108");
client_addr.sin_port = htons(PORT);
if((connect(client_fd,(SOCKADDR*)&client_addr,sizeof(client_addr)))==SOCKET_ERROR )
{
printf("connect error!");
closesocket(client_fd);
return -1;
}
return client_fd;
}
void client::recev(int client_fd)
{
char length[9]={0}; 
long tt ;
size_t l = recv(client_fd,(char*)&tt,8,0);


//size_t tt = (int)length;
//cout<<tt<<endl;
char *recvBuf= new char[tt];
int n =0;
int nread= 0;
//while((nread = recv(client_fd,recvBuf+n,BUFSIZE,0))>0)
//{
// n +=nread;
//}
recv(client_fd,recvBuf,tt,0);
std::string picall = recvBuf;
//pthread_t thread;
//if(pthread_create(thread,NULL,thread_func,NULL)!= 0)
//{
// return EXIT_FAILURE;
//}
Json::Reader reader;
Json::Value value;
const char* json_document = picall.c_str();
if(!reader.parse(json_document ,value))
printf("parse error!");
//reader.parse(json_document ,value);
/*std::cout<<value["content"]<<std::endl;
std::cout<<value["format"]<<std::endl;
std::cout<<value["size"]<<std::endl;*/

std::string pic = value["content"].asString();
//int size = value["size"].asInt();
std::string size = value["size"].asString();
const char* area = size.c_str();
int integerSize = atoi(area);
//cout<<size<<endl;
const char* picture = pic.c_str();
std::string coded = base64_decode(pic);


const char* pBuf = coded.c_str();
//写入刚才读取的文件
    FILE *pFileOut=fopen("d:/test32.jpg","wb");
    fwrite(pBuf,1,integerSize,pFileOut);
// fwrite(picture,1,len,pFileOut);
    fclose(pFileOut);
delete[] recvBuf;
}
//void ThreadFunc(PVOID PARAM)
//{
// client ctest;
// ctest.initSocket();
// int client_fd;
// client_fd = ctest.conne(func);
// ctest.recev(client_fd);
// //while(1)
// //{
// // //client_fd = ctest.conne(func);
// //   ctest.recev(client_fd);
// // func(1);
// //}
//}
//int main()
//{
// int i = 0;
// _beginthread(ThreadFunc,0,NULL);
// Sleep(50);
//   // free(pBuf); //释放
// return 0;
//}
int main()
{
client ctest;
ctest.initSocket();
int client_fd;
client_fd = ctest.conne(func);
ctest.recev(client_fd);
func(1);
return 0;
}

功能完全实现,因为CTO不想增加项目大小而没有去优化代码,做完整接口!仅供参考方便日后学习!