Visual Studio 2017开发linux程序之libevent使用实例
生活随笔
收集整理的這篇文章主要介紹了
Visual Studio 2017开发linux程序之libevent使用实例
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
下載源碼編譯安裝后,samle里面有個hello-world.c就是最簡單的一個tcp server端程序了
/*This example program provides a trivial server program that listens for TCPconnections on port 9995. When they arrive, it writes a short message toeach client connection, and closes each connection once it is flushed.Where possible, it exits cleanly in response to a SIGINT (ctrl-c). */#include <string.h> #include <errno.h> #include <stdio.h> #include <signal.h> #ifndef _WIN32 #include <netinet/in.h> # ifdef _XOPEN_SOURCE_EXTENDED # include <arpa/inet.h> # endif #include <sys/socket.h> #endif#include <event2/bufferevent.h> #include <event2/buffer.h> #include <event2/listener.h> #include <event2/util.h> #include <event2/event.h>static const char MESSAGE[] = "Hello, World!\n";static const int PORT = 9995;static void listener_cb(struct evconnlistener *, evutil_socket_t,struct sockaddr *, int socklen, void *); static void conn_writecb(struct bufferevent *, void *); static void conn_eventcb(struct bufferevent *, short, void *); static void signal_cb(evutil_socket_t, short, void *);int main(int argc, char **argv) {struct event_base *base;struct evconnlistener *listener;struct event *signal_event;struct sockaddr_in sin; #ifdef _WIN32WSADATA wsa_data;WSAStartup(0x0201, &wsa_data); #endifbase = event_base_new();if (!base) {fprintf(stderr, "Could not initialize libevent!\n");return 1;}memset(&sin, 0, sizeof(sin));sin.sin_family = AF_INET;sin.sin_port = htons(PORT);listener = evconnlistener_new_bind(base, listener_cb, (void *)base,LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_FREE, -1,(struct sockaddr*)&sin,sizeof(sin));if (!listener) {fprintf(stderr, "Could not create a listener!\n");return 1;}signal_event = evsignal_new(base, SIGINT, signal_cb, (void *)base);if (!signal_event || event_add(signal_event, NULL)<0) {fprintf(stderr, "Could not create/add a signal event!\n");return 1;}event_base_dispatch(base);evconnlistener_free(listener);event_free(signal_event);event_base_free(base);printf("done\n");return 0; }static void listener_cb(struct evconnlistener *listener, evutil_socket_t fd,struct sockaddr *sa, int socklen, void *user_data) {struct event_base *base = user_data;struct bufferevent *bev;bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);if (!bev) {fprintf(stderr, "Error constructing bufferevent!");event_base_loopbreak(base);return;}bufferevent_setcb(bev, NULL, conn_writecb, conn_eventcb, NULL);bufferevent_enable(bev, EV_WRITE);bufferevent_disable(bev, EV_READ);bufferevent_write(bev, MESSAGE, strlen(MESSAGE)); }static void conn_writecb(struct bufferevent *bev, void *user_data) {struct evbuffer *output = bufferevent_get_output(bev);if (evbuffer_get_length(output) == 0) {printf("flushed answer\n");bufferevent_free(bev);} }static void conn_eventcb(struct bufferevent *bev, short events, void *user_data) {if (events & BEV_EVENT_EOF) {printf("Connection closed.\n");} else if (events & BEV_EVENT_ERROR) {printf("Got an error on the connection: %s\n",strerror(errno));/*XXX win32*/}/* None of the other events can happen here, since we haven't enabled* timeouts */bufferevent_free(bev); }static void signal_cb(evutil_socket_t sig, short events, void *user_data) {struct event_base *base = user_data;struct timeval delay = { 2, 0 };printf("Caught an interrupt signal; exiting cleanly in two seconds.\n");event_base_loopexit(base, &delay); }設置好鏈接庫的路徑和鏈接庫
寫一個簡單的client端,代碼如下:
// sample_tcpclient.cpp : 定義控制臺應用程序的入口點。 //#include "stdafx.h"#include <stdio.h> #include <Winsock2.h> #include <mstcpip.h>#pragma comment(lib,"ws2_32.lib")#define _WINSOCK_DEPRECATED_NO_WARNINGSint main(int argc, char* argv[]) {WORD wVersionRequested;WSADATA wsaData;int err;wVersionRequested = MAKEWORD(1, 1);err = WSAStartup(wVersionRequested, &wsaData);if (err != 0) {printf("WSAStartup failed:%d\n", err);getchar();exit(0);}if (LOBYTE(wsaData.wVersion) != 1 ||HIBYTE(wsaData.wVersion) != 1) {WSACleanup();printf("version error\n");getchar();exit(0);} lab_start:SOCKET sockClient = socket(AF_INET, SOCK_STREAM, 0);SOCKADDR_IN addrSrv;addrSrv.sin_addr.S_un.S_addr = inet_addr("192.168.2.41");addrSrv.sin_family = AF_INET;addrSrv.sin_port = htons(9995);int ret = connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));if (ret != 0){printf("connect failed:%d\n", ret);return -1;}// 開啟KeepAliveBOOL bKeepAlive = TRUE;int nRet = ::setsockopt(sockClient, SOL_SOCKET, SO_KEEPALIVE, (char*)&bKeepAlive, sizeof(bKeepAlive));if (nRet == SOCKET_ERROR){printf("setsockopt error:%d\n", nRet);return -1;}// 設置KeepAlive參數tcp_keepalive alive_in = { 0 };tcp_keepalive alive_out = { 0 };alive_in.keepalivetime = 5000; // 開始首次KeepAlive探測前的TCP空閉時間alive_in.keepaliveinterval = 1000; // 兩次KeepAlive探測間的時間間隔alive_in.onoff = TRUE;unsigned long ulBytesReturn = 0;nRet = WSAIoctl(sockClient, SIO_KEEPALIVE_VALS, &alive_in, sizeof(alive_in),&alive_out, sizeof(alive_out), &ulBytesReturn, NULL, NULL);if (nRet == SOCKET_ERROR){printf("WSAIoctl error:%d\n", nRet);return -1;}//disable nagleint on = 1;/* make socket here */ #ifdef WIN32 setsockopt(sockClient, IPPROTO_TCP, TCP_NODELAY, (const char *)&on, sizeof(on)); #else setsockopt(sockClient, IPPROTO_TCP, TCP_NODELAY, (void *)&on, sizeof(on)); #endif const char *data_str = "hello world, i am client";int data_len = strlen(data_str)+1;for (int i = 0; i < 10; i++){ret = send(sockClient, data_str + (data_len - data_len % 1024), data_len % 1024, 0);if (ret < 0){printf("send error:%d\n", ret);break;}printf("data_len:%d count:%d ret:%d\n", data_len, i, ret);char recvBuf[256];ret = ::recv(sockClient, recvBuf, 256, 0);if (ret < 0){printf("recv error:%d\n", ret);break;}recvBuf[ret] = '\0';printf("ret:%d recv:%s\n", ret, recvBuf);Sleep(3000);}closesocket(sockClient);getchar();closesocket(sockClient);WSACleanup(); }然后就是連接成功了:
總結
以上是生活随笔為你收集整理的Visual Studio 2017开发linux程序之libevent使用实例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 统一建模语言UML要点全面简析
- 下一篇: 最简单的基于FFmpeg的AVfilte