1 #include<iostream>
2 #include<stdlib.h>
3 #include<sys/epoll.h>
4 #include<sys/socket.h>
5 #include<netinet/
in.h>
6 #include<sys/types.h>
7 #include<fcntl.h>
8
9
using
namespace std;
10
const
int PORT =
8888;
11
const
int MAX_CLIENT_NUM =
10000;
12
const
int MAX_LEN =
2000;
13
14
bool setfdnoblock(
int fd)
15 {
16
int flg = fcntl(fd, F_GETFL);
17
if(flg <
0)
18 {
19 cout <<
"
get fd flag failed
" << endl;
20
return
false;
21 }
22
if(fcntl(fd, F_SETFL, O_NONBLOCK | flg) <
0)
23 {
24
return
false;
25 }
26
return
true;
27 }
28
29
int CreateTcpServer(
int port,
int listennum)
30 {
31
int fd;
32 fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
33
34 sockaddr_in TcpServer;
35 bzero(&TcpServer,
sizeof(TcpServer));
36 TcpServer.sin_family = AF_INET;
37 TcpServer.sin_port = htons(
8888);
38 TcpServer.sin_addr.s_addr = htonl(INADDR_ANY);
39
40
int iRet = bind(fd, (
struct sockaddr*)&TcpServer,
sizeof(TcpServer));
41
if(-
1 == iRet)
42 {
43 cout <<
"
server bind error!
" << endl;
44
return -
1;
45 }
46
if(listen(fd, listennum) == -
1)
47 {
48 cout <<
"
server listen error
" << endl;
49
return -
1;
50 }
51
return fd;
52 }
53
54
int main()
55 {
56
int Serverfd = CreateTcpServer(PORT, MAX_CLIENT_NUM);
57
if(Serverfd == -
1)
58 {
59 cout <<
"
server create failed
" << endl;
60 }
61
else
62 {
63 cout <<
"
serverfd is :
" << Serverfd << endl;
64 }
65
66
int Epollfd = epoll_create(MAX_CLIENT_NUM);
67
if(Epollfd == -
1)
68 {
69 cout <<
"
epoll_create failed
" << endl;
70 }
71 epoll_event ev, events[MAX_CLIENT_NUM];
72
int nfds =
0;
73
int client =
0;
74
char buff[MAX_LEN];
75 sockaddr_in CliAddr;
76 unsigned
int iCliSize =
sizeof(CliAddr);
77 ev.events = EPOLLIN|EPOLLOUT;
78 ev.data.fd = Serverfd;
79
if(!setfdnoblock(Serverfd))
80 {
81 cout <<
"
set serverfd no_block failed
" << endl;
82 }
83
if(epoll_ctl(Epollfd, EPOLL_CTL_ADD, Serverfd, &ev))
84 {
85 cout <<
"
epoll add serverfd error
" << endl;
86 }
87
while(
1)
88 {
89 nfds = epoll_wait(Epollfd, events, MAX_CLIENT_NUM,
100000);
90
if(nfds == -
1)
91 {
92 cout <<
"
error occur, exit
" << endl;
93
return -
1;
94 }
95
else
if( nfds ==
0)
96 {
97 cout <<
"
epoll_wait return zero
" << endl;
98 }
99
else
100 {
101
for(
int i =
0; i < nfds; i++)
102 {
103 cout <<
"
events[i].data.fd is :
" << events[i].data.fd << endl;
104
if(events[i].data.fd == Serverfd)
105 {
106 cout <<
"
Serverfd received event
" << endl;
107 client = accept(Serverfd, (
struct sockaddr*)&CliAddr, &iCliSize);
108
if(client == -
1)
109 {
110 cout <<
"
accept error
" << endl;
111
return -
1;
112 }
113 ev.data.fd = client;
114
if(!setfdnoblock(client))
115 {
116 cout <<
"
set client fd no_block error
" << endl;
117 }
118
if(epoll_ctl(Epollfd, EPOLL_CTL_ADD, client, &ev))
119 {
120 cout <<
"
epoll add client error
" << endl;
121 }
122
else
123 {
124 cout <<
"
success add client
" << endl;
125 }
126 }
127
else
if(events[i].events&EPOLLIN)
128 {
129 cout <<
"
recv client msg
" << endl;
130
if(events[i].data.fd <
0)
131 {
132 cout <<
"
event[i].data.fd is smaller than zero
" << endl;
133
continue;
134 }
135
if(read(events[i].data.fd, buff, MAX_LEN) == -
1)
136 {
137 perror(
"
clifd read
");
138 }
139
else
140 {
141 cout <<
"
read client msg suc
" << endl;
142 printf(
"
%s
",buff);
143 }
144
char resp[] =
"
recv a client msg, this is resp msg
";
145 write(events[i].data.fd, resp, strlen(resp)+
1);
146
//
read and mod
147
}
148
else
if(events[i].events&EPOLLOUT)
149 {
150
//
send and mod
151
}
152 }
153 }
154 }
155 }
1 #include<sys/types.h>
2 #include<sys/socket.h>
3 #include<netinet/
in.h>
4 #include<stdlib.h>
5 #include<arpa/inet.h>
6 #include<stdio.h>
7 #include<
string.h>
8 #include<iostream>
9
10
using
namespace std;
11
const
int MAX_BUFF=
2048;
12
char notify[] =
"
i'm client
";
13
14
int main()
15 {
16
int Clifd;
17
char buff[MAX_BUFF];
18 Clifd = socket(AF_INET, SOCK_STREAM,
0);
19
if(Clifd == -
1)
20 {
21 perror(
"
clifd socket
");
22 }
23 sockaddr_in CliSock;
24 bzero(&CliSock,
sizeof(CliSock));
25 CliSock.sin_family = AF_INET;
26 CliSock.sin_addr.s_addr = inet_addr(
"
203.195.243.17
");
27 CliSock.sin_port = htons(
8888);
28
29
if(-
1 == connect(Clifd, (
struct sockaddr*)&CliSock,
sizeof(CliSock)))
30 {
31 perror(
"
clifd connect
");
32 }
33
if(write(Clifd, notify, strlen(notify)+
1) == -
1)
34 {
35 perror(
"
clifd write
");
36 }
37 cout <<
"
write over
" << endl;
38
if(read(Clifd, buff, MAX_BUFF) == -
1)
39 {
40 perror(
"
clifd read
");
41 }
42
else
43 {
44 cout << buff << endl;
45 }
46 }
1.epoll_ctl(Epollfd, EPOLL_CTL_ADD, Serverfd, &ev)添加Serverfd至epoll監視列表時ev.data.fd並無設置等於serverfd,結果客戶端來鏈接的時候不停收到EPOLLIN消息,但events[i].data.fd == Serverfd卻從不成立,在epoll_ctl以前添加ev.data.fd = Serverfd解決問題,對此個人理解是epoll_ctl將第三參數Serverfd加入監視列表,並將ev結構體與Serverfd關聯起來,但epoll不會主動監測和修改ev的其餘參數,在epoll_wait時epoll監測到Serverfd上有可讀的消息就返回,並將Serverfd關聯的ev結構體賦值給events這個事件列表,因此events[i].data.fd其實就是epoll_ctl註冊時的ev.data.fd。函數
2.當client代碼調用connect之後當即返回了鏈接創建成功的結果,此時epoll_server的accept函數尚未調用,那麼TCP的鏈接創建原理是怎樣的?學習
從這張圖片來看,TCP的server端在listen之後會被動接受client的請求並創建鏈接,accept和創建鏈接沒有直接關係,accept只是從serverfd上獲取到請求建連的client信息,accept以前已經完成了鏈路的建立。this
騰訊雲服務器真是一臺裸機,ftp服務沒有打開,默認只能ssh登錄root帳戶,man手冊用法有點奇怪,用了一天之後還報了hostname錯誤和eth1找不到網絡設備,感受不是很成熟的產品。