FaceServer/ev_proto.h | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
FaceServer/ev_server.cpp | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
FaceServer/ev_server.h | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
FaceServer/face_daemon_proto.h | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
FaceServer/facelist-3.pb | 补丁 | 查看 | 原始文档 | blame | 历史 | |
FaceServer/main_face_daemon.cpp | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
FaceServer/make.sh | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
FaceServer/test_client.cpp | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
FaceServer/ev_proto.h
@@ -3,8 +3,22 @@ #include <stddef.h> #include <stdint.h> #include <limits.h> #pragma pack(1) struct EVPProto { enum EVPP { EVPP__FIRST, EVPP_RAW_BIN = 1, EVPP_RAW_TEXT, EVPP_PROTOBUF, EVPP_HTTP, EVPP__LAST }; }; struct EVPCommand { @@ -13,7 +27,7 @@ EVPC__FIRST, EVPC_STATUS = 1, EVPC_USER_DEFINE = 128, EVPC__LAST EVPC__LAST = USHRT_MAX }; }; @@ -25,6 +39,8 @@ EVPS_OK = 1, EVPS_ERROR = 128, EVPS_INTERNAL_ERROR, EVPS_PROTO_ERROR, EVPS_COMMAND_ERROR, EVPS_PARAMETER_ERROR, EVPS__LAST }; @@ -32,8 +48,16 @@ struct EVPHeader { private: uint8_t _padding1; public: uint8_t proto; // EVPProto::EVPP int16_t cmd; // EVPCommand::EVPC uint32_t size; // sizeof(EVPHeader)+sizeof(subcmd) EVPHeader() : _padding1(0), proto(EVPProto::EVPP__FIRST), cmd(EVPCommand::EVPC__FIRST), size(8) {} }; struct EVP_Status FaceServer/ev_server.cpp
@@ -1,6 +1,6 @@ #include "ev_server.h" #include "ev_proto.h" #include "logger.h" #include <logger.h> #include <sys/types.h> #include <sys/socket.h> @@ -69,11 +69,11 @@ if (what & EVBUFFER_EOF) { //Client disconnected, remove the read event and the free the client structure. LOG_INFO << "Client disconnected." << std::endl; LOG_INFO << "Client disconnected." << LOG_ENDL; } else { LOG_WARN << "Client socket error, disconnecting." << std::endl; LOG_WARN << "Client socket error, disconnecting." << LOG_ENDL; } bufferevent_free(client->buf_ev); close(client->fd); @@ -89,12 +89,12 @@ // Write back the read buffer. It is important to note that // bufferevent_write_buffer will drain the incoming data so it // is effectively gone after we call it. //LOG_DEBUG << (char*)bufev->input << std::endl; //LOG_DEBUG << (char*)bufev->input << LOG_ENDL; //bufferevent_write_buffer(bufev, bufev->input); //char buff[100] = {'\0'}; //size_t readSize = bufferevent_read(bufev, buff, sizeof(buff)); //LOG_DEBUG << "readSize=" << readSize << "\t" << buff << std::endl; //LOG_DEBUG << "readSize=" << readSize << "\t" << buff << LOG_ENDL; EVPHeader* evpHeader = (EVPHeader*)client->recvbuff; @@ -107,7 +107,7 @@ client->read_times = 1; if (readSize != sizeof(headerBuff)) { LOG_WARN << "client send incomplete header" << std::endl; LOG_WARN << "client send incomplete header" << LOG_ENDL; buffered_on_error(bufev, 0, arg); return; } @@ -115,10 +115,11 @@ evpHeader = (EVPHeader*)headerBuff; // check header if (evpHeader->cmd <= EVPCommand::EVPC__FIRST || evpHeader->cmd >= EVPCommand::EVPC__LAST || if (evpHeader->proto <= EVPProto::EVPP__FIRST || evpHeader->proto >= EVPProto::EVPP__LAST || evpHeader->cmd <= EVPCommand::EVPC__FIRST || evpHeader->cmd >= EVPCommand::EVPC__LAST || evpHeader->size < sizeof(EVPHeader) || evpHeader->size > CLIENT_BUFFER_MAX) { LOG_WARN << "client send invalid header" << std::endl; LOG_WARN << "client send invalid header" << LOG_ENDL; buffered_on_error(bufev, 0, arg); return; } @@ -169,7 +170,7 @@ { size_t writeSize = bufferevent_write(bufev, cs.sendBuff, cs.sendBuffSize); if (writeSize != cs.sendBuffSize) LOG_WARN << "server send truncate " << (cs.sendBuffSize - writeSize) << " bytes" << std::endl; LOG_WARN << "server send truncate " << (cs.sendBuffSize - writeSize) << " bytes" << LOG_ENDL; if (cs.deleteSendBuff) delete[] cs.sendBuff; @@ -178,7 +179,7 @@ if (closeClient) { LOG_DEBUG << "server initiative close" << std::endl; LOG_DEBUG << "server initiative close" << LOG_ENDL; buffered_on_error(bufev, 0, arg); } @@ -190,7 +191,7 @@ // check read times if (client->read_times > CLIENT_READ_TIMES_MAX) { LOG_WARN << "client read times to max" << std::endl; LOG_WARN << "client read times to max" << LOG_ENDL; buffered_on_error(bufev, 0, arg); } } @@ -209,19 +210,19 @@ int client_fd = accept(fd, (struct sockaddr *)&client_addr, &client_len); if (client_fd < 0) { LOG_WARN << "accept failed" << std::endl; LOG_WARN << "accept failed" << LOG_ENDL; return; } // Set the client socket to non-blocking mode. if (setnonblock(client_fd) < 0) LOG_WARN << "failed to set client socket non-blocking" << std::endl; LOG_WARN << "failed to set client socket non-blocking" << LOG_ENDL; // We've accepted a new client, create a client object. struct EVClient* client = new EVClient; if (client == NULL) { LOG_ERROR << "malloc failed" << std::endl; LOG_ERROR << "malloc failed" << LOG_ENDL; } client->fd = client_fd; client->proc = evclient_proc; @@ -232,12 +233,12 @@ // We have to enable it before our callbacks will be called. bufferevent_enable(client->buf_ev, EV_READ); LOG_INFO << "Accepted connection from " << inet_ntoa(client_addr.sin_addr) << std::endl; LOG_INFO << "Accepted connection from " << inet_ntoa(client_addr.sin_addr) << LOG_ENDL; } int server_main(int argc, char **argv) { //initLogger(LV_DEBUG); LOG_NOTICE << "server_main" << LOG_ENDL; // Initialize libevent. event_init(); @@ -246,7 +247,7 @@ int listen_fd = socket(AF_INET, SOCK_STREAM, 0); if (listen_fd < 0) { LOG_ERROR << "create socket failed" << std::endl; LOG_ERROR << "create socket failed" << LOG_ENDL; return EXIT_FAILURE; } @@ -255,26 +256,28 @@ listen_addr.sin_family = AF_INET; listen_addr.sin_addr.s_addr = INADDR_ANY; listen_addr.sin_port = htons(SERVER_PORT); int reuseaddr_on = REUSEADDR_ON; setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr_on, sizeof(reuseaddr_on)); if (setnonblock(listen_fd) < 0) { LOG_ERROR << "failed to set server socket to non-blocking" << LOG_ENDL; return EXIT_FAILURE; } if (bind(listen_fd, (struct sockaddr *)&listen_addr, sizeof(listen_addr)) < 0) { LOG_ERROR << "bind failed" << std::endl; LOG_ERROR << "bind failed" << LOG_ENDL; return EXIT_FAILURE; } if (listen(listen_fd, 5) < 0) { LOG_ERROR << "listen failed" << std::endl; LOG_ERROR << "listen failed" << LOG_ENDL; return EXIT_FAILURE; } // Set the socket to non-blocking, this is essential in event based programming with libevent. int reuseaddr_on = REUSEADDR_ON; setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr_on, sizeof(reuseaddr_on)); if (setnonblock(listen_fd) < 0) { LOG_ERROR << "failed to set server socket to non-blocking" << std::endl; return EXIT_FAILURE; } // We now have a listening socket, we create a read event to be notified when a client connects. struct event ev_accept; @@ -284,9 +287,17 @@ // Start the event loop. event_dispatch(); close(listen_fd); listen_fd = 0; return EXIT_SUCCESS; } void server_stop() { LOG_NOTICE << "server_stop" << LOG_ENDL; event_loopexit(NULL); } void ev_send_status_packet(EVClientStub& client, EVPStatus::EVPS status) { client.sendBuffSize = sizeof(EVPHeader)+sizeof(EVP_Status); FaceServer/ev_server.h
@@ -41,6 +41,7 @@ //#define USER_DEFINE_EVCLIENT_PROC int server_main(int argc, char **argv); void server_stop(); void ev_send_packet(EVClientStub& client); void ev_send_status_packet(EVClientStub& client, EVPStatus::EVPS status); FaceServer/face_daemon_proto.h
New file @@ -0,0 +1,48 @@ #ifndef _FACE_DAEMON_PROTO_H_ #define _FACE_DAEMON_PROTO_H_ #include <stddef.h> #include <stdint.h> #include "ev_proto.h" #include <vector> #pragma pack(1) struct FaceDaemonCommand { enum FDC { FDC__FIRST, FDC_SENSETIMEFACEDETECT = EVPCommand::EVPC_USER_DEFINE + 1, // 129 FDC_SENSETIMEFACEDETECT_RESULT, FDC_SENSETIMEFACEDETECT_PB, FDC_SENSETIMEFACEDETECT_RESULT_JSON, FDC_SENSETIMEFACEDETECT_SAVE, FDC__LAST, }; }; struct FDP_Image { int32_t school_id; int16_t mb_type; // MB_Frame::MBFType int16_t width; int16_t height; uint8_t buff[0]; }; struct FDP_FaceDetectResult { int32_t db_id; int32_t st_id; // sensetime id FDP_FaceDetectResult(int32_t _db_id, int32_t _st_id) : db_id(_db_id), st_id(_st_id) {} }; #pragma pack() typedef std::vector<FDP_FaceDetectResult> fdr_vec_t; #endif FaceServer/facelist-3.pbBinary files differ
FaceServer/main_face_daemon.cpp
@@ -1,168 +1,99 @@ #include "PipeLine.h" #include "MaterialBuffer.h" #include "PL_RTSPClient.h" #include "PL_RTSPServer.h" #include "PL_H264Decoder.h" #include "PL_H264Encoder.h" #include "PL_AVFrameYUV420.h" #include "PL_AVFrameBGRA.h" #include "PL_Queue.h" #include "PL_Scale.h" #include "PL_Fork.h" #include "PL_Payer.h" #include "PL_Gainer.h" #include "PL_SensetimeFaceTrack.h" #include "PL_SensetimeFaceDetect.h" #include "PL_DlibFaceTrack.h" #include "PipeLinePool.h" #include <MaterialBuffer.h> #include <logger.h> #include "ev_server.h" #include "ev_proto.h" #include "face_daemon_proto.h" #include "SensetimeFaceAPIWrapper/src/FaceDBPool.h" #include "SensetimeFaceAPIWrapper/src/faceAPI.h" #include <PbFaceList.pb.h> #include "logger.h" #include <signal.h> template<typename TPoolPtr, typename TPoolElem> struct PoolElemLocker { TPoolPtr pool; TPoolElem elem; PoolElemLocker(TPoolPtr _pool, TPoolElem _elem) : pool(_pool), elem(_elem) { #include <sstream> #include <iostream> } ~PoolElemLocker() { pool->release(elem); pool->notify_free(); } }; template<typename TArrayPtr> struct ArrayDeleter { TArrayPtr array; ArrayDeleter(TArrayPtr _array) : array(_array) { } ~ArrayDeleter() { delete[] array; } }; PipeLinePool g_PipeLinePool; FaceDBPool g_faceAPIPool;//#todo config Logger g_logger(std::cout); evclient_proc_t evclient_proc; bool send_SensetimeFaceDetectResult(EVClientStub& client, PipeMaterial& lastPm) void _sigint(int sign_no) { //if (lastPm.type != PipeMaterial::PMT_PM_LIST) //PipeMaterial& facePM = ((PipeMaterial*)(lastPm.buffer))[1]; //st_ff_vect_t& faceFeatures = *((st_ff_vect_t*)facePM.buffer); //LOG_NOTICE << "faceFeatures " << faceFeatures.size() << std::endl; //#todo send result packet if (lastPm.buffer == nullptr || lastPm.type != PipeMaterial::PMT_BYTES || lastPm.buffSize != sizeof(SensetimeFaceDetectResult)) { LOG_WARN << "pm not available" << std::endl; ev_send_status_packet(client, EVPStatus::EVPS_INTERNAL_ERROR); return false; server_stop(); } const SensetimeFaceDetectResult* result = (const SensetimeFaceDetectResult*)lastPm.buffer; bool send_SensetimeFaceDetectResultJson(EVClientStub& client, const fdr_vec_t& result) { std::stringstream ss; ss << "{" << std::endl; ss << "\"ret\":" << 0 << "," << std::endl; ss << "\"count\":" << result.size() << "," << std::endl; ss << "\"result\":["; for(fdr_vec_t::const_iterator iter = result.begin(); iter != result.end(); ++iter) { ss << "[" << iter->db_id << "," << iter->st_id << "]"; if (iter != std::prev(result.end())) ss << ","; } ss << "]" << std::endl; ss << "}"; client.sendBuffSize = sizeof(EVPHeader)+sizeof(SensetimeFaceDetectResult); std::string output(ss.str());//#todo avoid copy client.sendBuffSize = output.size() + 1; client.sendBuff = new uint8_t[client.sendBuffSize]; strcpy((char*)client.sendBuff, output.c_str()); client.deleteSendBuff = true; EVPHeader* evpHeader = new (client.sendBuff) EVPHeader; evpHeader->cmd = FaceDaemonCommand::FDC_SENSETIMEFACEDETECT_RESULT; evpHeader->size = client.sendBuffSize; SensetimeFaceDetectResult* evpSub = new (client.sendBuff + sizeof(EVPHeader)) SensetimeFaceDetectResult; evpSub->school_id = result->school_id; evpSub->st_id = result->st_id; LOG_DEBUG << (char*)client.sendBuff << LOG_ENDL; return true; } bool ev_proc_SensetimeFaceDetect(EVClientStub& client) bool ev_proc_SensetimeFaceDetectPB(EVClientStub& client) { //#test send 01000B0000004142434445 //#test send //00038300FE4B0000+pb //EVPHeader* evpHeader = (EVPHeader*)client.recvBuff; //LOG_DEBUG << "cmd=" << evpHeader->cmd << ", size=" << evpHeader->size << ", \t" << (char*)(evpHeader + sizeof(EVPHeader)) << std::endl; //return true; FDP_Image* fdpImage = (FDP_Image*)(client.recvBuff + sizeof(EVPHeader)); EVPHeader* evpHeader = (EVPHeader*)client.recvBuff; FaceDB* _faceDB = g_faceAPIPool.get_free(fdpImage->school_id); if (_faceDB == nullptr) PbFaceList pbFaceList; pbFaceList.ParseFromArray(client.recvBuff + sizeof(EVPHeader), evpHeader->size - sizeof(EVPHeader)); LOGP(DEBUG, "pbFaceList: magic=%u, image_count=%u, src_width=%u, src_height=%u", pbFaceList.magic(), pbFaceList.image_count(), pbFaceList.src_width(), pbFaceList.src_height()); for(int i = 0; i < pbFaceList.image_count(); i++) { LOG_WARN << "can't get face db" << std::endl; ev_send_status_packet(client, EVPStatus::EVPS_PARAMETER_ERROR); return false; const PbFaceList_FaceListImage& pbFaceListImage = pbFaceList.images(i); LOGP(DEBUG, "\tpbFaceList %d: idx=%u, size=%u, type=%u, width=%u, height=%u, top_left_x=%u, top_left_y=%u", i, pbFaceListImage.idx(), pbFaceListImage.size(), pbFaceListImage.type(), pbFaceListImage.width(), pbFaceListImage.height(), pbFaceListImage.top_left_x(), pbFaceListImage.top_left_y()); char imgfn[100 * 1024]; sprintf(imgfn, "PB_%d_%d.yuv", 0, i); FILE * pFile = fopen(imgfn, "wb"); fwrite(*(pbFaceListImage.img().data()), sizeof(char), pbFaceListImage.size(), pFile); fclose(pFile); pFile = nullptr; } PoolElemLocker<FaceDBPool*, int> _lock_faceAPI(&g_faceAPIPool, fdpImage->school_id); PipeLine* pipeLine = g_PipeLinePool.get_free(); if (pipeLine == nullptr) { LOG_WARN << "can't get free pipeline" << std::endl; ev_send_status_packet(client, EVPStatus::EVPS_INTERNAL_ERROR); return false; } fdr_vec_t result; PoolElemLocker<PipeLinePool*, PipeLine*> _lock_pipeLine(&g_PipeLinePool, pipeLine); //do detect(client) result.push_back(FDP_FaceDetectResult(-1,123)); result.push_back(FDP_FaceDetectResult(2,456)); result.push_back(FDP_FaceDetectResult(0,0)); // fill SensetimeFaceDetectDbFrame dbFrame; dbFrame.type = (MB_Frame::MBFType)(fdpImage->mb_type); dbFrame.buffSize = client.recvBuffSize - sizeof(EVPHeader) - sizeof(FDP_Image); dbFrame.buffer = new uint8_t[dbFrame.buffSize]; ArrayDeleter<uint8_t*> _del_img((uint8_t*)dbFrame.buffer); memcpy(dbFrame.buffer, fdpImage->buff, dbFrame.buffSize); dbFrame.width = fdpImage->width; dbFrame.height = fdpImage->height; dbFrame.school_id = fdpImage->school_id; dbFrame._faceDB = _faceDB; PipeMaterial pm; pm.type = PipeMaterial::PMT_FRAME; pm.buffer = &dbFrame; pm.buffSize = 0; PipeLineElem* plElem = pipeLine->pipe(&pm); if (! pipeLine->check_pipe_complete(plElem)) { LOG_WARN << "pipeline not complete" << std::endl; ev_send_status_packet(client, EVPStatus::EVPS_INTERNAL_ERROR); return false; } if (!plElem->gain(pm)) { LOG_WARN << "pipeline gain error" << std::endl; ev_send_status_packet(client, EVPStatus::EVPS_INTERNAL_ERROR); return false; } // can not release pipleline unless pm not used send_SensetimeFaceDetectResult(client, pm); send_SensetimeFaceDetectResultJson(client, result); return false; } bool ev_proc(EVClientStub& client) bool ev_dispatcher_proto_pb(EVClientStub& client) { LOG_DEBUG << "ev_dispatcher_proto_pb" << LOG_ENDL; EVPHeader* evpHeader = (EVPHeader*)client.recvBuff; if (evpHeader->size != client.recvBuffSize) { @@ -172,12 +103,40 @@ switch(evpHeader->cmd) { case EVPCommand::EVPC_USER_DEFINE + 1: return ev_proc_SensetimeFaceDetect(client); case FaceDaemonCommand::FDC_SENSETIMEFACEDETECT_PB: //000383000800000001 return ev_proc_SensetimeFaceDetectPB(client); break; default: LOG_WARN << "Unknown command" << std::endl; ev_send_status_packet(client, EVPStatus::EVPS_PARAMETER_ERROR); ev_send_status_packet(client, EVPStatus::EVPS_COMMAND_ERROR); return false; break; } // return false to disconnect return false; } bool ev_dispatcher_proto(EVClientStub& client) { LOG_DEBUG << "ev_dispatcher_proto" << LOG_ENDL; EVPHeader* evpHeader = (EVPHeader*)client.recvBuff; if (evpHeader->size != client.recvBuffSize) { LOG_WARN << "Truncated buffer " << (evpHeader->size - client.recvBuffSize) << " bytes" << std::endl; return false; } switch(evpHeader->proto) { case EVPProto::EVPP_PROTOBUF: return ev_dispatcher_proto_pb(client); break; default: LOG_WARN << "Unknown proto" << std::endl; ev_send_status_packet(client, EVPStatus::EVPS_PROTO_ERROR); return false; break; } @@ -188,46 +147,10 @@ int main(int argc, char** argv) { initLogger(LV_DEBUG); g_logger.set_level(VERBOSE); PipeLine::register_global_elem_creator("PL_SensetimeFaceTrack", create_PL_SensetimeFaceTrack); PipeLine::register_global_elem_creator("PL_Gainer", create_PL_Gainer); signal(SIGINT, _sigint); g_PipeLinePool = new PipeLinePool(true); for (int i = 0; i < 5; i++) { PipeLine* pipeLine = new PipeLine; { PL_Payer_Config config; config.copyData = true;//#todo false PL_Gainer* ple = (PL_Gainer*)pipeLine->push_elem("PL_Gainer"); bool ret = ple->init(&config); if (!ret) { LOG_ERROR << "ple init error" << std::endl; exit(EXIT_FAILURE); } } { SensetimeFaceTrackConfig config; config.draw_face_rect = false; config.draw_face_feature_point = false; config.generate_face_feature = true; PL_SensetimeFaceTrack* ple = (PL_SensetimeFaceTrack*)pipeLine->push_elem("PL_SensetimeFaceTrack"); bool ret = ple->init(&config); if (!ret) { LOG_ERROR << "ple init error" << std::endl; exit(EXIT_FAILURE); } } g_PipeLinePool.manage(pipeLine); } evclient_proc = ev_proc; evclient_proc = ev_dispatcher_proto; return server_main(argc, argv); } FaceServer/make.sh
New file @@ -0,0 +1,38 @@ #!/bin/sh PIPELINE_BASE=/opt/RtspFace VISITFACE_BASE=/opt/VisitFace/RtspNativeCodec/app/src/main/cpp PROTOBUF_BASE=/opt/protobuf/inst PROTOBUF_INC="-I$PROTOBUF_BASE/include" PROTOBUF_LIB="-L$PROTOBUF_BASE/lib -lprotobuf" CPPFLAGS+="-g -c -std=c++11 -pthread -I$PIPELINE_BASE -I$VISITFACE_BASE $PROTOBUF_INC " LDFLAGS+="-pthread -levent $PROTOBUF_LIB " rm *.o rm face_server rm test_client g++ $PIPELINE_BASE/Logger/src/logger.cc $CFLAGS $CPPFLAGS g++ ev_server.cpp -DUSER_DEFINE_EVCLIENT_PROC $CFLAGS $CPPFLAGS g++ main_face_daemon.cpp $CFLAGS $CPPFLAGS g++ $VISITFACE_BASE/PbFaceList.pb.cc $CFLAGS $CPPFLAGS g++ test_client.cpp $CFLAGS $CPPFLAGS g++ -g -std=c++11 \ logger.o \ ev_server.o \ PbFaceList.pb.o \ main_face_daemon.o \ $LDFLAGS -o face_server # g++ -g -std=c++11 \ test_client.o \ $LDFLAGS -o test_client # #export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/protobuf/inst/lib FaceServer/test_client.cpp
New file @@ -0,0 +1,97 @@ /************************************ * For msmr * server.c * tesing the speed of bufferevent_write * 2015-02-03 * author@tom ************************************/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <event2/event.h> #include <event2/bufferevent.h> #include <event2/buffer.h> #include <netinet/tcp.h> #include <arpa/inet.h> #include <unistd.h> #include "ev_proto.h" #include "face_daemon_proto.h" void make_msg(char* mesg, int length) { EVPHeader* evpHeader = new (mesg) EVPHeader; evpHeader->proto = EVPProto::EVPP_PROTOBUF; evpHeader->cmd = FaceDaemonCommand::FDC_SENSETIMEFACEDETECT_PB; evpHeader->size = length; FILE* pFile = fopen("facelist-3.pb", "rb"); size_t fsize = fread(mesg + sizeof(EVPHeader), 1, length - sizeof(EVPHeader), pFile); fclose(pFile); } int main() { // build the message to be sent int length = 19454; // the size of message char* mesg = (char*)malloc((length+1)*sizeof(char)); // Look out the end mark '/0' of a C string if (mesg == NULL) exit(1); int i; //for (i=0; i<length; i++) // strcat(mesg, "a"); make_msg(mesg, length); printf("%s\n", mesg); printf("%d\n", (int)strlen(mesg)); // build socket int port = 5432; struct sockaddr_in server_addr; memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = inet_addr("192.168.1.146"); server_addr.sin_port = htons(port); // build event base struct event_base* base = event_base_new(); // set TCP_NODELAY to let data arrive at the server side quickly evutil_socket_t fd; fd = socket(AF_INET, SOCK_STREAM, 0); struct bufferevent* conn = bufferevent_socket_new(base,fd,BEV_OPT_CLOSE_ON_FREE); int enable = 1; if(setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (void*)&enable, sizeof(enable)) < 0) printf("ERROR: TCP_NODELAY SETTING ERROR!\n"); //bufferevent_setcb(conn, NULL, NULL, NULL, NULL); // For client, we don't need callback function bufferevent_enable(conn, EV_WRITE); if(bufferevent_socket_connect(conn,(struct sockaddr*)&server_addr,sizeof(server_addr)) == 0) printf("connect success\n"); // start to send data bufferevent_write(conn,mesg,length); // check the output evbuffer struct evbuffer* output = bufferevent_get_output(conn); int len = 0; len = evbuffer_get_length(output); printf("output buffer has %d bytes left\n", len); event_base_dispatch(base); //char readbuf[100*1024]; //int readbufsize = read(fd, readbuf, sizeof(readbuf)); //printf("read:\n%s\n", readbuf); free(mesg); mesg = NULL; bufferevent_free(conn); event_base_free(base); printf("Client program is over\n"); return 0; }