I/O示例使用一个windows平台上服务器/客户端的例子来演示。由于为了减少代码篇幅等各种由于本人懒而产生的原因,以下代码没有做错误处理以及有些小问题,但是我想应该不影响演示,大家多包涵。
服务器代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
#include <stdio.h> #define WIN32_LEAN_AND_MEAN #include <windows.h> #include <winsock2.h> #include "event.h" #include "event_struct.h" #include "evutil.h" #define PORT 4000 #define IP_ADDRESS "172.16.80.101" #define MEM_SIZE 1024 struct event_base* base;
struct sock_ev
{ struct event* read_ev;
struct event* write_ev;
char * buffer;
}; void release_sock_event( struct sock_ev* ev)
{ event_del(ev->read_ev);
free (ev->read_ev);
free (ev->write_ev);
free (ev->buffer);
free (ev);
return ;
} void on_write( int sock, short event, void * arg)
{ char * buffer = ( char *)arg;
send(sock, buffer, strlen (buffer), 0);
printf ( "on_write\n" );
free (buffer);
return ;
} void on_read( int sock, short event, void * arg)
{ struct event* write_ev;
int size;
struct sock_ev* ev = ( struct sock_ev*)arg;
printf ( "on_read\n" );
ev->buffer = ( char *) malloc (MEM_SIZE);
memset (ev->buffer, 0, MEM_SIZE);
size = recv(sock, ev->buffer, MEM_SIZE, 0);
printf ( "receive data:%s, size:%d\n" , ev->buffer, size);
if (size == 0)
{
release_sock_event(ev);
close(sock);
return ;
}
event_assign(ev->write_ev, base, sock, EV_WRITE, on_write, ev->buffer);
event_add(ev->write_ev, NULL);
return ;
} void on_accept( int sock, short event, void * arg)
{ struct sockaddr_in cli_addr;
int fd, sin_size;
struct sock_ev* ev = ( struct sock_ev*) malloc ( sizeof ( struct sock_ev));
printf ( "on_accept\n" );
ev->read_ev = ( struct event*) malloc ( sizeof ( struct event));
ev->write_ev = ( struct event*) malloc ( sizeof ( struct event));
sin_size = sizeof ( struct sockaddr_in);
fd = accept(sock, ( struct sockaddr*)&cli_addr, &sin_size);
event_assign(ev->read_ev, base, fd, EV_READ|EV_PERSIST, on_read, ev);
event_add(ev->read_ev, NULL);
return ;
} int main( int argc, char * argv[])
{ WSADATA ws;
SOCKET srvSock;
struct sockaddr_in sockAddr;
struct event ev_listen;
WSAStartup(MAKEWORD(2,2), &ws);
srvSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
sockAddr.sin_family = AF_INET;
sockAddr.sin_addr.s_addr = inet_addr(IP_ADDRESS);
sockAddr.sin_port = htons(PORT);
memset (sockAddr.sin_zero, 0, sizeof (sockAddr.sin_zero));
bind(srvSock, ( struct sockaddr*)&sockAddr, sizeof (sockAddr));
listen(srvSock, 10);
base = event_base_new();
event_assign(&ev_listen, base, srvSock, EV_READ|EV_PERSIST, on_accept, NULL);
event_add(&ev_listen, NULL);
event_base_dispatch(base);
closesocket(srvSock);
WSACleanup();
return 0;
} |
|
|
客户端代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
#include "stdafx.h" #include <stdio.h> #define WIN32_LEAN_AND_MEAN #include <windows.h> #include <winsock2.h> #include "event.h" #include "event_struct.h" #include "evutil.h" #define PORT 4000 #define IP_ADDRESS "172.16.80.101" int main( int argc, char * argv[])
{ WSADATA ws;
SOCKET cltSocket;
struct sockaddr_in sockAddr;
int Ret = 0;
WSAStartup(MAKEWORD(2,2), &ws);
cltSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
sockAddr.sin_family = AF_INET;
sockAddr.sin_addr.s_addr = inet_addr(IP_ADDRESS);
sockAddr.sin_port = htons(PORT);
memset (sockAddr.sin_zero, 0, sizeof (sockAddr.sin_zero));
connect(cltSocket,( struct sockaddr*)&sockAddr, sizeof (sockAddr));
//send
char SendBuffer[MAX_PATH] = "test" ;
Ret = send(cltSocket, SendBuffer, ( int ) strlen (SendBuffer), 0);
printf ( "send size=%d.\n" , Ret);
//recv
char recvBuf[50] = {0};
if ( 0 > recv(cltSocket, recvBuf, 50, 0) )
{
printf ( "recv fail.\n" );
return 0;
}
printf ( "%s\n" , recvBuf);
while (1)
{
Sleep(1000);
}
closesocket(cltSocket);
WSACleanup();
return 0;
} |
服务器的功能主要是接收客户端发来的数据,并返回给客户端。
客户端的功能主要是连接服务器后向服务器发送数据,然后读取服务器发来的数据。
下面分下以下代码流程:
客户端就不分析了,都是老套路。
服务器端:
(1) 首先添加一个永久的读类型的事件,指定的文件描述符是我们监听的socket。当有客户端来connect,这个事件会触发,触发回调函数on_accept()。
(2) 在on_accept()中accept后,在新的文件描述符上添加一个永久的读事件,当文件操作符可读,调用on_read()读取。
(3) 在on_read()中为了将数据写会给客户端,添加了一个写事件,这次的写事件不是永久的,只会触发一次,因为我们只将读取到的数据回给客户端一次。当文件描述符可写,触发回调函数on_write()写入给客户端。
(4) On_write()写入数据。
libevent I/O示例的更多相关文章
-
php libevent 扩展使用示例
<?php define()); define()); class epoll{ private static $socket; public static $connections; priv ...
-
Linux下libevent安装与示例
http://www.cnblogs.com/kunhu/p/3632225.html
-
示例的libevent的程序
著作权归作者所有. 商业转载请联系作者获得授权,非商业转载请注明出处. 作者:auxten 链接:http://zhuanlan.zhihu.com/auxten/20315482 来源:知乎 /* ...
-
libevent使用IOCP网络模型的示例
这段时间抽空学习了一下强大的网络库libevent,其使用标准C语言编写,支持Windows.Linux.Mac等等主流操作系统,早期版本不支持Windows的IOCP,最新版本已经添加上了,在网上找 ...
-
libevent 信号示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 3 ...
-
libevent 定时器示例
程序执行结果: 每隔2秒,触发一次定时器. (2)98行:evtimer_assign在event.h中定义如下: 再来看看event_assign函数: ev 要初始化的事件对象 base ...
-
libevent带负载均衡的多线程使用示例
功能: 主线程根据负载工作线程负载均衡算法,每隔一秒钟向特定的工作线程发送一条字符串信息,工作线程简单的把字符串信息打开出来. Makefile eventtest : eventtest.c ...
-
Libevent初探
Libevent 是一个用C语言编写的.轻量级的开源高性能网络库,主要有以下几个亮点:事件驱动( event-driven),高性能;轻量级,专注于网络,不如 ACE 那么臃肿庞大:源代码相当精炼.易 ...
-
【转】libevent源码分析
libevent源码分析 转自:http://www.cnblogs.com/hustcat/archive/2010/08/31/1814022.html 这两天没事,看了一下Memcached和l ...
随机推荐
-
overflow遭遇场景
没有设置高度而由内容撑高的子div在遇到固定高度的父div,想做一个离上边缘有间距的效果,给padding-top会同时撑大父div,给margin-top会把父div拉下来,这时候的子div像是紧紧 ...
-
IOS SizeClasses 详解
SizeClasses 详解 iOS 8在应用界面的可视化设计上添加了一个新的特性-Size Classes.对于任何设备来说,界面的宽度和高度都只分为三种描述:紧凑,任意和宽松.这样开发者便可以无视 ...
-
Java Hour 27 Concurrent
有句名言,叫做10000小时成为某一个领域的专家.姑且不辩论这句话是否正确,让我们到达10000小时的时候再回头来看吧. 27 Hours. 本小时主要过一下多线程相关的基本API. Defining ...
-
Codeforces Gym 100637A A. Nano alarm-clocks 前缀和处理
A. Nano alarm-clocks Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100637/p ...
-
关于ComponentName的使用
ComponentName,顾名思义,就是组件名称,通过调用Intent中的setComponent方法,我们可以打开另外一个应用中的Activity或者服务. 实例化一个ComponentName需 ...
-
oracle学习----去除表中的重复数据
重复的数据可能有这样两种情况,第一种:表中只有某些字段一样,第二种:两行记录完全一样.第一.对于部分字段重复数据的删除 先来谈谈如何查询重复的数据吧. 下面语句可以查询出那 ...
-
Jquyer相册
点击图片然后弹出相册列表,效果如下: html代码: <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml&q ...
-
win10、Ubuntu14.04双系统正确卸载Ubuntu的方法
参考博客:http://www.cnblogs.com/xia-Autumn/p/6294055.html 问题描述:由于python问题Ubuntu系统崩了,登录之后无法进入桌面.重装桌面时报错,无 ...
-
Codeforces 436E Cardboard Box (看题解)
Cardboard Box 贪了个半天贪不对, 我发现我根本就不会贪心. 我们先按b排序, 然后枚举选两颗心的b的最大值, 在这个之前的肯定都要选一个, 因为前面的要是一个都没选的话, 你可以把当前选 ...
-
oracle 数据库、实例、服务名、SID
参考:http://www.zhetao.com/content240 在实际的开发应用中,关于Oracle数据库,经常听见有人说建立一个数据库,建立一个Instance,启动一个Instance之类 ...