3
3
namespace net
4
4
{
5
5
6
- IoSocket::IoSocket ()
6
+ IoSocket::IoSocket ():
7
+ _close (false )
7
8
{
8
9
_fd = INVALID_SOCKET;
9
10
_loop = NULL ;
10
11
_event._type = SEpollEvent::eEPV_SOCKET;
11
12
_event._ev .data .ptr = &_event;
12
13
13
- isconnect = false ;
14
+ _isconnect = false ;
14
15
_recv.reset ();
15
16
_writeBuf = NULL ;
16
17
_writeLen = 0 ;
17
18
}
18
19
19
20
IoSocket::~IoSocket ()
20
21
{
21
- close ();
22
+ finalClose ();
22
23
}
23
24
24
25
bool IoSocket::connect (NetLoop* loop, const char * ip, unsigned short port)
@@ -40,13 +41,15 @@ namespace net
40
41
}
41
42
42
43
_event._ev .events = EPOLLET | EPOLLOUT;
43
- _event.outptr = shared_from_this ();
44
- loop->registerEpoll (EPOLL_CTL_ADD, fd, &_event._ev );
44
+ if (!loop->registerEpoll (EPOLL_CTL_ADD, fd, &_event._ev ))
45
+ {
46
+ return false ;
47
+ }
45
48
46
49
_fd = fd;
47
50
_loop = loop;
48
- isconnect = true ;
49
-
51
+ _isconnect = true ;
52
+ _event. sockptr = shared_from_this ();
50
53
return true ;
51
54
}
52
55
@@ -68,13 +71,17 @@ namespace net
68
71
}
69
72
70
73
_event._ev .events = EPOLLET | EPOLLOUT;
71
- _event.outptr = shared_from_this ();
72
- _loop->registerEpoll (EPOLL_CTL_ADD, fd, &_event._ev );
73
-
74
+ if (!_loop->registerEpoll (EPOLL_CTL_ADD, fd, &_event._ev ))
75
+ {
76
+ return false ;
77
+ }
78
+
74
79
_fd = fd;
75
- isconnect = true ;
80
+ _isconnect = true ;
81
+ _event.sockptr = shared_from_this ();
76
82
return true ;
77
83
}
84
+
78
85
bool IoSocket::write (char * buf, int len)
79
86
{
80
87
int ret = send (_fd, buf, len, 0 );
@@ -88,8 +95,10 @@ namespace net
88
95
89
96
// EPOLLOUT
90
97
_event._ev .events = _event._ev .events | EPOLLOUT;
91
- _event.outptr = shared_from_this ();
92
- _loop->registerEpoll (EPOLL_CTL_MOD, _fd, &_event._ev );
98
+ if (!_loop->registerEpoll (EPOLL_CTL_MOD, _fd, &_event._ev )){
99
+ return false ;
100
+ }
101
+ _event.sockptr = shared_from_this ();
93
102
}
94
103
else
95
104
{
@@ -99,21 +108,25 @@ namespace net
99
108
return true ;
100
109
101
110
}
111
+
102
112
bool IoSocket::read (char * buf, int len)
103
113
{
114
+ if (buf == NULL || len <= 0 ) return false ;
115
+
104
116
if (!(_event._ev .events & EPOLLIN))
105
117
{
106
118
_event._ev .events = _event._ev .events | EPOLLIN;
107
- _loop->registerEpoll (EPOLL_CTL_MOD, _fd, &_event._ev );
119
+ if (!_loop->registerEpoll (EPOLL_CTL_MOD, _fd, &_event._ev )){
120
+ return false ;
121
+ }
122
+ _event.sockptr = shared_from_this ();
108
123
}
109
124
110
- _event.inptr = shared_from_this ();
111
-
112
125
_recv._recvBuf = buf;
113
126
_recv._recvLen = len;
114
-
115
- handleRead ();
116
-
127
+ if (_recv. _hasData ) {
128
+ handleRead ();
129
+ }
117
130
return true ;
118
131
}
119
132
@@ -128,142 +141,108 @@ namespace net
128
141
129
142
void IoSocket::onEpollEv (uint32 ev)
130
143
{
131
- if (isconnect )
144
+ if (_isconnect )
132
145
{
133
- int result = 0 ;
134
- if (ev & EPOLLERR || ev & EPOLLHUP)
135
- {
136
- // WRITE_LOG("IoSocket::onEpollEv EPOLLERR || EPOLLHUP errno: %d error:%s, line:%d\n", errno, strerror(errno), __LINE__);
137
- result = errno;
138
- }
139
- else if (ev & EPOLLOUT)
140
- {
141
- // 连接成功
142
- result = 0 ;
146
+ _isconnect = false ;
147
+ if (ev & EPOLLERR || ev & EPOLLHUP){
148
+ this ->finalClose (); // reconnect close this socket
149
+ onConnect (errno == 0 ? 0xffffffff : errno);
143
150
}
144
- else
145
- {
146
- WRITE_LOG (" IoSocket::onEpollEv Handling Exceptions line:%d\n " , __LINE__);
147
- return ;
148
- }
149
-
150
- isconnect = false ;
151
- IoSockptr tmpptr (std::move (_event.outptr ));
152
- if (result == 0 ) {
151
+ else if (ev & EPOLLOUT){ // connect success
153
152
_event._ev .events = _event._ev .events & ~EPOLLOUT;
154
153
_loop->registerEpoll (EPOLL_CTL_MOD, _fd, &_event._ev );
154
+ onConnect (0 );
155
155
}
156
156
else {
157
- this -> close ( );
157
+ assert ( 0 );
158
158
}
159
- onConnect (result);
160
159
return ;
161
160
}
162
161
163
- if (ev & EPOLLHUP || ev & EPOLLERR)
164
- {
165
- WRITE_LOG (" IoSocket::onEpollEv EPOLLERR || EPOLLHUP errno: %d error:%s, line:%d\n " , errno, strerror (errno), __LINE__);
166
- IoSockptr inptr (std::move (_event.inptr ));
167
- IoSockptr outptr (std::move (_event.outptr ));
168
- this ->close ();
169
- onRead (0 , errno);
162
+ if (ev & EPOLLHUP ||// shtdown (recive bytes == 0 && errno == 0)
163
+ ev & EPOLLERR){ // opposite close (errno > 0)
164
+ onRead (0 , errno == 0 ? 0xffffffff : errno);
170
165
return ;
171
166
}
172
167
173
- // read
168
+
174
169
if (ev & EPOLLIN)
175
170
{
176
-
177
- _recv._isRead = true ;
178
- handleRead ();
179
- #if 0
180
- int ret = recv(_fd, _recvBuf, _recvLen, 0);
181
- if (ret < 0){
182
- if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK){
183
- return;
184
- }
185
- else{
186
- onRead(ret, errno);
187
- return;
188
- }
189
- }
190
- else if (ret == 0){
191
- //close
192
- onRead(ret, errno);
193
- return;
171
+ _recv._hasData = true ;
172
+ if (_recv.isValid ()) {
173
+ handleRead ();
194
174
}
195
- onRead(ret, 0);
196
- #endif
197
175
}
198
-
199
- // write
200
- if (ev & EPOLLOUT)
176
+ else if (ev & EPOLLOUT)
201
177
{
202
178
int err = 0 ;
203
- int ret = send (_fd, _writeBuf, _writeLen, 0 );
204
- if (ret < 0 )
179
+ while (1 )
205
180
{
206
- if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) {
207
- return ;
181
+ int ret = send (_fd, _writeBuf, _writeLen, 0 );
182
+ if (ret < 0 )
183
+ {
184
+ if (errno == EINTR) continue ;
185
+ if (errno == EAGAIN || errno == EWOULDBLOCK) {
186
+ return ;
187
+ }
188
+ else {
189
+ err = errno;
190
+ }
208
191
}
209
- else {
210
- // onWrite(ret, errno);
211
- // return;
212
- err = errno;
213
- }
214
- }
215
192
216
- // 取消EPOLLOUT
217
- _event._ev .events = _event._ev .events & ~EPOLLOUT;
218
- _loop->registerEpoll (EPOLL_CTL_MOD, _fd, &_event._ev );
219
- IoSockptr tmpptr (std::move (_event.outptr ));
193
+ // È¡ÏûEPOLLOUT
194
+ _event._ev .events = _event._ev .events & ~EPOLLOUT;
195
+ _loop->registerEpoll (EPOLL_CTL_MOD, _fd, &_event._ev );
220
196
221
- onWrite (ret, err);
197
+ onWrite (ret, err);
198
+ return ;// exec one
199
+ };
222
200
}
223
201
}
224
202
225
- void IoSocket::handleRead ()
203
+ bool IoSocket::handleRead ()
226
204
{
227
- if (!_recv.isValid () || !_recv._isRead ) return ;
228
-
229
- int result = 0 ;
230
- // while(1){ recv();} ==> 替换成在onRead递归
231
- int ret = recv (_fd, _recv._recvBuf , _recv._recvLen , 0 );
232
- if (ret < 0 ) {
233
- if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) {
234
- return ;
205
+ while (1 )
206
+ {
207
+ int result = 0 ;
208
+ int bytes = recv (_fd, _recv._recvBuf , _recv._recvLen , 0 );
209
+ if (bytes < 0 ) {
210
+ if (errno == EINTR) continue ;
211
+ if (errno == EAGAIN || errno == EWOULDBLOCK) {
212
+ return false ;
213
+ }
214
+ _recv._hasData = false ;
215
+ result = errno;
235
216
}
236
- else {
237
- _recv._isRead = false ;
217
+ else if (bytes == 0 ){ // close
218
+ _recv._hasData = false ;
238
219
result = errno;
239
220
}
240
- }
241
- else if (ret == 0 ) {
242
- // close
243
- _recv._isRead = false ;
244
- result = errno;
245
- }
246
- else {
247
- // ret > 0
248
- }
249
221
250
- _recv._recvBuf = NULL ;
251
- _recv._recvLen = 0 ;
252
- IoSockptr tmpptr (std::move (_event.inptr ));
253
- onRead (ret, result);
222
+ _recv.setInvalid ();
223
+ onRead (bytes, result);
224
+ return true ;// exec one
225
+
226
+ };
254
227
}
255
228
256
229
void IoSocket::close ()
230
+ {
231
+ if (_close) return ;
232
+ _close = true ;
233
+
234
+ if (_fd != INVALID_SOCKET){
235
+ ::shutdown (_fd, SHUT_RDWR);
236
+ }
237
+ }
238
+
239
+ void IoSocket::finalClose ()
257
240
{
258
241
if (_fd != INVALID_SOCKET)
259
242
{
260
- _event.inptr = nullptr ;
261
- _event.outptr = nullptr ;
262
-
263
243
if (_loop) {
264
244
_loop->registerEpoll (EPOLL_CTL_DEL, _fd, &_event._ev );
265
245
}
266
- ::shutdown (_fd, SHUT_RDWR);
267
246
::close (_fd);
268
247
_fd = INVALID_SOCKET;
269
248
}
0 commit comments