epoll实现TCP通信
来源:互联网 发布:pooled ols对截面数据 编辑:程序博客网 时间:2024/06/07 08:37
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
//初级版
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<sys/epoll.h>
#define _SIZE_ 64
#define _BACKLOG_ 5
typedef
struct
fdBuf
{
void
* _buf;
int
_fd;
}fdBuf;
static
void
usage(
const
char
* proc)
{
printf
(
"%s [ip][port]"
,proc);
}
static
int
startup(
char
* ip,
int
port)
{
int
listen_sock=socket(AF_INET,SOCK_STREAM,0);
if
(listen_sock<0)
{
perror
(
"socket"
);
exit
(1);
}
struct
sockaddr_in local;
local.sin_family=AF_INET;
local.sin_port=htons(port);
local.sin_addr.s_addr=inet_addr(ip);
if
(bind(listen_sock,(
struct
sockaddr*)&local,
sizeof
(local))<0)
{
perror
(
"bind"
);
exit
(2);
}
if
(listen(listen_sock,_BACKLOG_)<0)
{
perror
(
"listen"
);
exit
(3);
}
return
listen_sock;
}
int
sock_epoll(
int
listen_sock)
{
//1.create fds instance
int
ins=epoll_create(_SIZE_);
if
(ins<0)
{
perror
(
"poll_create"
);
return
1;
}
struct
epoll_event ev;
ev.events=EPOLLIN;
ev.data.fd=listen_sock;
int
i=0;
//index
fdBuf bufs[_SIZE_];
for
(i=0;i<_SIZE_;++i)
{
bufs[i]._fd=-1;
bufs[i]._buf=NULL;
}
struct
epoll_event fds[_SIZE_];
//with bufs save buf
for
(i=0;i<_SIZE_;++i)
{
fds[i].events=0;
fds[i].data.fd=-1;
}
epoll_ctl(ins,EPOLL_CTL_ADD,listen_sock,&ev);
int
ret=-1;
int
timeout=5000;
struct
sockaddr_in remote;
socklen_t len=
sizeof
(remote);
ssize_t _s;
//charnum
while
(1)
{
switch
((ret=epoll_wait(ins,fds,64,timeout)))
{
case
-1:
//error
perror
(
"epoll_wait"
);
break
;
case
0:
//time out
printf
(
"time is out\n"
);
break
;
default
:
{
for
(i=0;i<ret;++i)
{
//printf("%d",ret);
if
(fds[i].data.fd==listen_sock)
{
if
(new_sock<0)
{
perror
(
"accept"
);
continue
;
}
ev.events=EPOLLIN;
ev.data.fd=new_sock;
epoll_ctl(ins,EPOLL_CTL_ADD,new_sock,&ev);
}
else
if
(fds[i].data.fd>0&&fds[i].events&EPOLLIN)
{
if
(bufs[i]._fd==-1)
{
char
*buf=(
char
*)
malloc
(
sizeof
(
char
)*1024);
bufs[i]._fd=fds[i].data.fd;
bufs[i]._buf=buf;
}
//save buf and fd
memset
(bufs[i]._buf,
'\0'
,1024);
//sleep(1);
fflush
(stdout);
_s=read(fds[i].data.fd,bufs[i]._buf,
sizeof
(bufs[i]._buf)-1);
if
(_s>0)
{
((
char
*)bufs[i]._buf)[_s]=
'\0'
;
printf
(
"client:%s"
,(
char
*)bufs[i]._buf);
//输出
ev.events=EPOLLOUT;
ev.data.fd=fds[i].data.fd;
epoll_ctl(ins,EPOLL_CTL_MOD,fds[i].data.fd,&ev);
}
else
if
(_s==0)
{
printf
(
"client is close...\n"
);
free
(bufs[i]._buf);
bufs[i]._fd=-1;
bufs[i]._buf=NULL;
//remove
epoll_ctl(ins,EPOLL_CTL_DEL,fds[i].data.fd,NULL);
}
else
{}
}
else
if
(fds[i].data.fd>0&&fds[i].events&EPOLLOUT)
{
write(fds[i].data.fd,bufs[i]._buf,
strlen
(bufs[i]._buf));
ev.events=EPOLLIN;
ev.data.fd=fds[i].data.fd;
epoll_ctl(ins,EPOLL_CTL_MOD,fds[i].data.fd,&ev);
}
else
{}
}
break
;
}
//default end
}
//switch end
}
//while end
}
int
main(
int
argc,
char
* argv[])
{
if
(argc!=3)
{
usage(argv[0]);
return
1;
}
int
_port=
atoi
(argv[2]);
char
* _ip=argv[1];
int
listen_sock=startup(_ip,_port);
sock_epoll(listen_sock);
close(listen_sock);
return
0;
}
//client
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
static
void
usage(
const
char
* proc)
{
printf
(
"%s [i][port]"
,proc);
}
int
main(
int
argc,
char
* argv[])
{
if
(argc!=3)
{
usage(argv[0]);
return
1;
}
int
sock=socket(AF_INET,SOCK_STREAM,0);
if
(sock<0)
{
perror
(
"socket"
);
return
2;
}
struct
sockaddr_in local;
local.sin_family=AF_INET;
local.sin_port=htons(
atoi
(argv[2]));
local.sin_addr.s_addr=inet_addr(argv[1]);
if
(connect(sock,(
struct
sockaddr*)&local,
sizeof
(local))<0)
{
perror
(
"connect"
);
return
3;
}
char
buf[1024];
ssize_t _s;
while
(1)
{
printf
(
"please input\n"
);
fflush
(stdout);
_s=read(0,buf,
sizeof
(buf)-1);
if
(_s>0)
{
buf[_s]=
'\0'
;
if
(
strncmp
(buf,
"quit"
,4)==0)
{
close(sock);
return
0;
}
write(sock,buf,
strlen
(buf));
}
else
if
(_s==0)
{
close(sock);
return
1;
}
_s=read(sock,buf,
sizeof
(buf)-1);
if
(_s>0)
{
buf[_s]=
'\0'
;
printf
(
"echo:%s\n"
,buf);
}
}
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
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
//server_epoll
#include<stdio.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<sys/epoll.h>
#include<assert.h>
#include<string.h>
#include<errno.h>
#define _MAX_FD_NUM_ 64
typedef
struct
_fd_buf
{
int
fd;
char
buf[1024];
}fdBuf_t,*fdBuf_p;
static
void
usage(
const
char
*
const
proc)
{
assert
(proc);
printf
(
"usage:%s[ip][port]"
,proc);
}
static
int
start(
char
* ip,
int
port)
{
assert
(ip);
int
sock=socket(AF_INET,SOCK_STREAM,0);
if
(sock<0)
{
perror
(
"socket"
);
exit
(1);
}
struct
sockaddr_in local;
local.sin_family=AF_INET;
local.sin_port=htons(port);
local.sin_addr.s_addr=inet_addr(ip);
//reuse socket
int
opt=1;
setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&opt,
sizeof
(opt));
if
(bind(sock,(
struct
sockaddr*)&local,
sizeof
(local))<0)
{
perror
(
"bind"
);
exit
(2);
}
if
(listen(sock,5)<0)
{
perror
(
"listen"
);
exit
(3);
}
return
sock;
}
static
int
epoll_server(
int
sock)
{
int
epoll_fd=epoll_create(256);
//-1 or fd
if
(epoll_fd<0)
{
perror
(
"epoll_create"
);
return
-1;
}
struct
epoll_event ev;
ev.events=EPOLLIN;
ev.data.fd=sock;
//0 success or -1 fail
if
(epoll_ctl(epoll_fd,EPOLL_CTL_ADD,sock,&ev)<0)
{
perror
(
"epoll_ctl"
);
return
-1;
}
struct
epoll_event fds[_MAX_FD_NUM_];
int
ret=-1;
int
timeout=5000;
int
i=0;
struct
sockaddr_in client;
socklen_t len=
sizeof
(client);
ssize_t _s=-1;
while
(1)
{
switch
((ret=epoll_wait(epoll_fd,fds,_MAX_FD_NUM_,timeout)))
{
case
-1:
//error
perror
(
"epoll_wait"
);
break
;
case
0:
printf
(
"time out...\n"
);
break
;
default
:
{
for
(i=0;i<ret;++i)
{
//listen ready
if
(fds[i].data.fd==sock&&fds[i].events&EPOLLIN)
{
int
new_sock=accept(sock,(
struct
sockaddr*)&client,&len);
if
(new_sock<0)
{
perror
(
"accept"
);
continue
;
}
ev.events=EPOLLIN;
ev.data.fd=new_sock;
epoll_ctl(epoll_fd,EPOLL_CTL_ADD,new_sock,&ev);
}
else
//normal socket
{
if
(fds[i].events&EPOLLIN)
{
fdBuf_p mem=(fdBuf_p)
malloc
(
sizeof
(fdBuf_t));
_s=read(fds[i].data.fd,mem->buf,
sizeof
(mem->buf)-1);
if
(_s>0)
{
mem->fd=fds[i].data.fd;
(mem->buf)[_s]=
'\0'
;
fds[i].data.ptr=mem;
printf
(
"client:%s"
,mem->buf);
ev.events=EPOLLOUT;
ev.data.ptr=mem;
epoll_ctl(epoll_fd,EPOLL_CTL_MOD,mem->fd,&ev);
}
else
if
(_s==0)
{
free
(mem);
close(fds[i].data.fd);
continue
;
epoll_ctl(epoll_fd,EPOLL_CTL_DEL,fds[i].data.fd,NULL);
}
else
{}
}
else
if
(fds[i].events&EPOLLOUT)
{
fdBuf_p cur=(fdBuf_p)fds[i].data.ptr;
write(cur->fd,cur->buf,
strlen
(cur->buf));
close(cur->fd);
epoll_ctl(epoll_fd,EPOLL_CTL_DEL,cur->fd,NULL);
free
(cur);
}
else
{}
}
}
}
break
;
}
}
}
int
main(
int
argc,
char
* argv[])
{
if
(argc!=3)
{
usage(argv[0]);
return
-1;
}
char
* ip=argv[1];
int
port=
atoi
(argv[2]);
int
listen_sock=start(ip,port);
epoll_server(listen_sock);
close(listen_sock);
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
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>
#include<unistd.h>
#include<fcntl.h>
static
void
setnoblock(
int
fd)
{
//get flag
int
fl=fcntl(fd,F_GETFL);
//arg is ignore
if
(fl<0)
{
perror
(
"fcntl"
);
exit
(1);
}
//set flag
if
(fcntl(fd,F_SETFL,fl|O_NONBLOCK))
//isn't 0 is error
{
perror
(
"fcntl"
);
exit
(1);
}
}
int
main()
{
setnoblock(0);
char
buf[20];
ssize_t _s=-1;
while
(1)
{
memset
(buf,
'\0'
,20);
_s=read(0,buf,
sizeof
(buf)-1);
if
(_s>0)
{
buf[_s]=
'\0'
;
printf
(
"echo:%s"
,buf);
}
else
if
(_s==0)
{
//do nothing
}
else
{
if
(
errno
==EAGAIN)
//EAGAIN==11
{
printf
(
"no data\n"
);
}
}
sleep(1);
}
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
//read
static
int
readData(
int
sock,
char
* buf,
int
size)
{
assert
(buf);
memset
(buf,
'\0'
,size);
int
i=0;
int
ret=-1;
while
((ret=read(sock,buf+i,size-i))<size)
{
if
(
errno
==EAGAIN)
break
;
i+=ret;
}
return
i;
}
//write
static
int
writeData(
int
sock,
char
* buf,
int
size)
{
assert
(buf);
int
i=0;
int
ret=-1;
while
((ret=write(sock,buf+i,size-i))<size)
{
if
(
errno
==EAGAIN)
break
;
i+=ret;
}
return
i;
}
//修改e所有关心操作符的vents
struct
epoll_event ev;
ev.events=EPOLLIN|EPOLLET;
ev.data.fd=sock;
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
#include<stdio.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<sys/epoll.h>
#include<assert.h>
#include<fcntl.h>
#include<unistd.h>
#include<string.h>
#include<errno.h>
#define _MAX_FD_NUM_ 64
typedef
struct
_fd_buf
{
int
fd;
char
buf[1024];
}fdBuf_t,*fdBuf_p;
static
void
setnoblock(
int
fd)
{
int
fl=fcntl(fd,F_GETFL);
if
(fl<0)
{
perror
(
"fcntl"
);
exit
(1);
}
if
(fcntl(fd,F_SETFL,fl|O_NONBLOCK))
{
perror
(
"fcntl"
);
exit
(1);
}
}
static
void
usage(
const
char
*
const
proc)
{
assert
(proc);
printf
(
"usage:%s[ip][port]"
,proc);
}
static
int
start(
char
* ip,
int
port)
{
assert
(ip);
int
sock=socket(AF_INET,SOCK_STREAM,0);
if
(sock<0)
{
perror
(
"socket"
);
exit
(1);
}
struct
sockaddr_in local;
local.sin_family=AF_INET;
local.sin_port=htons(port);
local.sin_addr.s_addr=inet_addr(ip);
//reuse socket
int
opt=1;
setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&opt,
sizeof
(opt));
if
(bind(sock,(
struct
sockaddr*)&local,
sizeof
(local))<0)
{
perror
(
"bind"
);
exit
(2);
}
if
(listen(sock,5)<0)
{
perror
(
"listen"
);
exit
(3);
}
return
sock;
}
//read
static
int
readData(
int
sock,
char
* buf,
int
size)
{
assert
(buf);
memset
(buf,
'\0'
,size);
int
i=0;
int
ret=-1;
while
((ret=read(sock,buf+i,size-i))<size)
{
if
(
errno
==EAGAIN)
break
;
i+=ret;
}
return
i;
}
//write
static
int
writeData(
int
sock,
char
* buf,
int
size)
{
assert
(buf);
int
i=0;
int
ret=-1;
while
((ret=write(sock,buf+i,size-i))<size)
{
if
(
errno
==EAGAIN)
break
;
i+=ret;
}
return
i;
}
static
int
epoll_server(
int
sock)
{
int
epoll_fd=epoll_create(256);
//-1 or fd
if
(epoll_fd<0)
{
perror
(
"epoll_create"
);
return
-1;
}
struct
epoll_event ev;
setnoblock(sock);
ev.events=EPOLLIN|EPOLLET;
ev.data.fd=sock;
//0 success or -1 fail
if
(epoll_ctl(epoll_fd,EPOLL_CTL_ADD,sock,&ev)<0)
{
perror
(
"epoll_ctl"
);
return
-1;
}
struct
epoll_event fds[_MAX_FD_NUM_];
int
ret=-1;
int
timeout=5000;
int
i=0;
struct
sockaddr_in client;
socklen_t len=
sizeof
(client);
ssize_t _s=-1;
while
(1)
{
switch
((ret=epoll_wait(epoll_fd,fds,_MAX_FD_NUM_,timeout)))
{
case
-1:
//error
perror
(
"epoll_wait"
);
break
;
case
0:
printf
(
"time out...\n"
);
break
;
default
:
{
for
(i=0;i<ret;++i)
{
//listen ready
if
(fds[i].data.fd==sock&&fds[i].events&EPOLLIN)
{
int
new_sock=accept(sock,(
struct
sockaddr*)&client,&len);
if
(new_sock<0)
{
perror
(
"accept"
);
continue
;
}
setnoblock(new_sock);
printf
(
"get a connect\n"
);
ev.events=EPOLLIN|EPOLLET;
ev.data.fd=new_sock;
epoll_ctl(epoll_fd,EPOLL_CTL_ADD,new_sock,&ev);
}
else
//normal socket
{
if
(fds[i].events&EPOLLIN)
{
fdBuf_p mem=(fdBuf_p)
malloc
(
sizeof
(fdBuf_t));
//_s=read(fds[i].data.fd,mem->buf,sizeof(mem->buf)-1);
_s=readData(fds[i].data.fd,mem->buf,
sizeof
(mem->buf));
if
(_s>0)
{
mem->fd=fds[i].data.fd;
(mem->buf)[_s]=
'\0'
;
fds[i].data.ptr=mem;
printf
(
"client:%s"
,mem->buf);
ev.events=EPOLLOUT|EPOLLET;
ev.data.ptr=mem;
epoll_ctl(epoll_fd,EPOLL_CTL_MOD,mem->fd,&ev);
}
else
if
(_s==0)
{
free
(mem);
close(fds[i].data.fd);
continue
;
epoll_ctl(epoll_fd,EPOLL_CTL_DEL,fds[i].data.fd,NULL);
}
else
{}
}
else
if
(fds[i].events&EPOLLOUT)
{
//char* buf="http/1.0 200 ok\r\n\r\nhello:)\r\n";
fdBuf_p cur=(fdBuf_p)fds[i].data.ptr;
//write(cur->fd,cur->buf,strlen(cur->buf));
//write(cur->fd,buf,strlen(buf));
writeData(cur->fd,cur->buf,
strlen
(cur->buf));
close(cur->fd);
epoll_ctl(epoll_fd,EPOLL_CTL_DEL,cur->fd,NULL);
free
(cur);
}
else
{}
}
}
}
break
;
}
}
}
int
main(
int
argc,
char
* argv[])
{
if
(argc!=3)
{
usage(argv[0]);
return
-1;
}
char
* ip=argv[1];
int
port=
atoi
(argv[2]);
int
listen_sock=start(ip,port);
epoll_server(listen_sock);
close(listen_sock);
return
0;
}
0 0
- epoll实现TCP通信
- 使用epoll实现TCP多路复用
- epoll实现服务端异步通信
- epoll实现linux进程通信
- epoll实现linux进程通信
- TCP通信C++实现
- python实现TCP通信
- C++实现TCP通信。。
- TCP实现P2P通信
- Qt-----实现Tcp通信
- TCP通信的实现
- TCP通信实现
- socket实现TCP通信
- TCP通信+域名解析实现:
- C++实现TCP通信
- (五)epoll实现TCP服务端
- linux 使用epoll实现网络通信
- Epoll 的tcp通信代码(服务器+客户端)
- spring 实现数据库读写分离
- C# 方法和属性的访问权限修饰符解析
- 工具类
- 堆栈排序算法
- PHP安全编程之表单与数据安全
- epoll实现TCP通信
- Linux中文件查找方法
- sentos yum安装mysql
- 调用shell命令 - 去除结尾的换行符
- 【POJ 2377 Bad Cowtractors】
- [李景山php]每天laravel-20161009|Validator.php-9
- 在网页中引用DWG控件,交互绘图,和响应鼠标点击对象的方法
- 2570 迷瘴
- Android评论功能的实现