GetQueuedCompletionStatus continues to select events on closed sockets
IOCP server works with WebSocket connections. When the browser sends a close frame, the server delete
s this client, the closesocket
function is calling in client's object destructor. But even after the socket was closed, the GetQueuedCompletionStatus
function continues to select events from this socket. Of course the result is false
and 0 bytes transferred, but Client ptr and OVERLAPPED
ptr are not NULL, and GetLastError
returns 1236 (ERROR_CONNECTION_ABORTED)... so yeah, it is aborted, and the closesocket
was called... But why it is still here??? And how to stop receiving this "useless" events? I can call continue
in thead's loop, but it will waste CPU time if the function will select this removed client forever.
Here is the part of worker thread's loop:
while(WAIT_OBJECT_0 != WaitForSingleObject(EventShutdown, 0)){
DWORD BytesTransfered = 0;
OVERLAPPED *asyncinfo = nullptr;
client *Client = nullptr;
BOOL QCS = GetQueuedCompletionStatus(hIOCP, &BytesTransfered, (PULONG_PTR)&Client, &asyncinfo, INFINITE);
if(!Client ) break;
switch( QCS * (BytesTransfered > 0) * Client->OpCode() ){
case OP_TYPE_RECV:{
.....
switch( recv_buf[0] &0xFF ){
....
case FIN_CLOSE:
printf("FIN_CLOSE on client %un", Client->Socket());
default:{
RemoveClient(Client);
break;
}
}
}
case OP_TYPE_SEND:{
...
}
default:{
printf("Client %u (%lu bytes transferred, QCS is %d)n", Client->Socket(), BytesTransfered, QCS);
break;
}
Client's destructor:
client::~client(){
while(!HasOverlappedIoCompleted(&asyncinfo)) Sleep(0);
closesocket(socket);
if( a_ctx ) delete a_ctx;
if( q_ctx ) delete q_ctx;
delete data_buffer;
printf("Client %u deletedn", socket);
}
... and the server's log:
Client 296 from 127.0.0.1 (agent 1987)
Client 308 from 127.0.0.1
(supervisor)
Client 324 from 127.0.0.1 (supervisor)
TOTAL: 3
client(s)
Sending 33278 bytes to 324
Send finished for 324
Send finished for 308
Sending 40529 bytes to 324
Send finished
for 324
Sending 41128 bytes to 324
Send finished for 324
Sending 40430 bytes to 324
Send finished for 324
FIN_CLOSE on
client 324
Client 324 deleted
Client 324 (0 bytes transferred,
QCS is 0)
Client 324 (0 bytes transferred, QCS is 0)
Client
324 (0 bytes transferred, QCS is 0)
Client 324 (0 bytes
transferred, QCS is 0)
Client 324 (0 bytes transferred, QCS is
0)
See that "324 (0 bytes transferred, QCS is 0)"? Socket 324 closed. Why it happens after destructor's message "Client 324 deleted"?
c++ winsock iocp
add a comment |
IOCP server works with WebSocket connections. When the browser sends a close frame, the server delete
s this client, the closesocket
function is calling in client's object destructor. But even after the socket was closed, the GetQueuedCompletionStatus
function continues to select events from this socket. Of course the result is false
and 0 bytes transferred, but Client ptr and OVERLAPPED
ptr are not NULL, and GetLastError
returns 1236 (ERROR_CONNECTION_ABORTED)... so yeah, it is aborted, and the closesocket
was called... But why it is still here??? And how to stop receiving this "useless" events? I can call continue
in thead's loop, but it will waste CPU time if the function will select this removed client forever.
Here is the part of worker thread's loop:
while(WAIT_OBJECT_0 != WaitForSingleObject(EventShutdown, 0)){
DWORD BytesTransfered = 0;
OVERLAPPED *asyncinfo = nullptr;
client *Client = nullptr;
BOOL QCS = GetQueuedCompletionStatus(hIOCP, &BytesTransfered, (PULONG_PTR)&Client, &asyncinfo, INFINITE);
if(!Client ) break;
switch( QCS * (BytesTransfered > 0) * Client->OpCode() ){
case OP_TYPE_RECV:{
.....
switch( recv_buf[0] &0xFF ){
....
case FIN_CLOSE:
printf("FIN_CLOSE on client %un", Client->Socket());
default:{
RemoveClient(Client);
break;
}
}
}
case OP_TYPE_SEND:{
...
}
default:{
printf("Client %u (%lu bytes transferred, QCS is %d)n", Client->Socket(), BytesTransfered, QCS);
break;
}
Client's destructor:
client::~client(){
while(!HasOverlappedIoCompleted(&asyncinfo)) Sleep(0);
closesocket(socket);
if( a_ctx ) delete a_ctx;
if( q_ctx ) delete q_ctx;
delete data_buffer;
printf("Client %u deletedn", socket);
}
... and the server's log:
Client 296 from 127.0.0.1 (agent 1987)
Client 308 from 127.0.0.1
(supervisor)
Client 324 from 127.0.0.1 (supervisor)
TOTAL: 3
client(s)
Sending 33278 bytes to 324
Send finished for 324
Send finished for 308
Sending 40529 bytes to 324
Send finished
for 324
Sending 41128 bytes to 324
Send finished for 324
Sending 40430 bytes to 324
Send finished for 324
FIN_CLOSE on
client 324
Client 324 deleted
Client 324 (0 bytes transferred,
QCS is 0)
Client 324 (0 bytes transferred, QCS is 0)
Client
324 (0 bytes transferred, QCS is 0)
Client 324 (0 bytes
transferred, QCS is 0)
Client 324 (0 bytes transferred, QCS is
0)
See that "324 (0 bytes transferred, QCS is 0)"? Socket 324 closed. Why it happens after destructor's message "Client 324 deleted"?
c++ winsock iocp
add a comment |
IOCP server works with WebSocket connections. When the browser sends a close frame, the server delete
s this client, the closesocket
function is calling in client's object destructor. But even after the socket was closed, the GetQueuedCompletionStatus
function continues to select events from this socket. Of course the result is false
and 0 bytes transferred, but Client ptr and OVERLAPPED
ptr are not NULL, and GetLastError
returns 1236 (ERROR_CONNECTION_ABORTED)... so yeah, it is aborted, and the closesocket
was called... But why it is still here??? And how to stop receiving this "useless" events? I can call continue
in thead's loop, but it will waste CPU time if the function will select this removed client forever.
Here is the part of worker thread's loop:
while(WAIT_OBJECT_0 != WaitForSingleObject(EventShutdown, 0)){
DWORD BytesTransfered = 0;
OVERLAPPED *asyncinfo = nullptr;
client *Client = nullptr;
BOOL QCS = GetQueuedCompletionStatus(hIOCP, &BytesTransfered, (PULONG_PTR)&Client, &asyncinfo, INFINITE);
if(!Client ) break;
switch( QCS * (BytesTransfered > 0) * Client->OpCode() ){
case OP_TYPE_RECV:{
.....
switch( recv_buf[0] &0xFF ){
....
case FIN_CLOSE:
printf("FIN_CLOSE on client %un", Client->Socket());
default:{
RemoveClient(Client);
break;
}
}
}
case OP_TYPE_SEND:{
...
}
default:{
printf("Client %u (%lu bytes transferred, QCS is %d)n", Client->Socket(), BytesTransfered, QCS);
break;
}
Client's destructor:
client::~client(){
while(!HasOverlappedIoCompleted(&asyncinfo)) Sleep(0);
closesocket(socket);
if( a_ctx ) delete a_ctx;
if( q_ctx ) delete q_ctx;
delete data_buffer;
printf("Client %u deletedn", socket);
}
... and the server's log:
Client 296 from 127.0.0.1 (agent 1987)
Client 308 from 127.0.0.1
(supervisor)
Client 324 from 127.0.0.1 (supervisor)
TOTAL: 3
client(s)
Sending 33278 bytes to 324
Send finished for 324
Send finished for 308
Sending 40529 bytes to 324
Send finished
for 324
Sending 41128 bytes to 324
Send finished for 324
Sending 40430 bytes to 324
Send finished for 324
FIN_CLOSE on
client 324
Client 324 deleted
Client 324 (0 bytes transferred,
QCS is 0)
Client 324 (0 bytes transferred, QCS is 0)
Client
324 (0 bytes transferred, QCS is 0)
Client 324 (0 bytes
transferred, QCS is 0)
Client 324 (0 bytes transferred, QCS is
0)
See that "324 (0 bytes transferred, QCS is 0)"? Socket 324 closed. Why it happens after destructor's message "Client 324 deleted"?
c++ winsock iocp
IOCP server works with WebSocket connections. When the browser sends a close frame, the server delete
s this client, the closesocket
function is calling in client's object destructor. But even after the socket was closed, the GetQueuedCompletionStatus
function continues to select events from this socket. Of course the result is false
and 0 bytes transferred, but Client ptr and OVERLAPPED
ptr are not NULL, and GetLastError
returns 1236 (ERROR_CONNECTION_ABORTED)... so yeah, it is aborted, and the closesocket
was called... But why it is still here??? And how to stop receiving this "useless" events? I can call continue
in thead's loop, but it will waste CPU time if the function will select this removed client forever.
Here is the part of worker thread's loop:
while(WAIT_OBJECT_0 != WaitForSingleObject(EventShutdown, 0)){
DWORD BytesTransfered = 0;
OVERLAPPED *asyncinfo = nullptr;
client *Client = nullptr;
BOOL QCS = GetQueuedCompletionStatus(hIOCP, &BytesTransfered, (PULONG_PTR)&Client, &asyncinfo, INFINITE);
if(!Client ) break;
switch( QCS * (BytesTransfered > 0) * Client->OpCode() ){
case OP_TYPE_RECV:{
.....
switch( recv_buf[0] &0xFF ){
....
case FIN_CLOSE:
printf("FIN_CLOSE on client %un", Client->Socket());
default:{
RemoveClient(Client);
break;
}
}
}
case OP_TYPE_SEND:{
...
}
default:{
printf("Client %u (%lu bytes transferred, QCS is %d)n", Client->Socket(), BytesTransfered, QCS);
break;
}
Client's destructor:
client::~client(){
while(!HasOverlappedIoCompleted(&asyncinfo)) Sleep(0);
closesocket(socket);
if( a_ctx ) delete a_ctx;
if( q_ctx ) delete q_ctx;
delete data_buffer;
printf("Client %u deletedn", socket);
}
... and the server's log:
Client 296 from 127.0.0.1 (agent 1987)
Client 308 from 127.0.0.1
(supervisor)
Client 324 from 127.0.0.1 (supervisor)
TOTAL: 3
client(s)
Sending 33278 bytes to 324
Send finished for 324
Send finished for 308
Sending 40529 bytes to 324
Send finished
for 324
Sending 41128 bytes to 324
Send finished for 324
Sending 40430 bytes to 324
Send finished for 324
FIN_CLOSE on
client 324
Client 324 deleted
Client 324 (0 bytes transferred,
QCS is 0)
Client 324 (0 bytes transferred, QCS is 0)
Client
324 (0 bytes transferred, QCS is 0)
Client 324 (0 bytes
transferred, QCS is 0)
Client 324 (0 bytes transferred, QCS is
0)
See that "324 (0 bytes transferred, QCS is 0)"? Socket 324 closed. Why it happens after destructor's message "Client 324 deleted"?
c++ winsock iocp
c++ winsock iocp
asked Nov 20 '18 at 12:33
IcemanIceman
17819
17819
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
I don't think you've included enough code to get a complete picture, but this line looks suspect:
switch( QCS * (BytesTransfered > 0) * Client->OpCode() ){
This is problematic for a couple of reasons. First, GetQueuedCompletionStatus
is not guaranteed to return 1 on success. MSDN promises only that it will return nonzero. Relying on a specific value for the success case is therefore risky. Second, you have no way to distinguish between a failed call and a successful call that returns 0 bytes. You should really separate your logic for managing the dequeue and for dispatching particular I/O events. This will make your code easier to understand and maintain.
You must also remember that there are two sides to every socket. There are the structures and socket handle you associate with it in user space, and then there are kernel objects that manage the low level details. Just because you close your handle on the user side does not mean that the kernel objects go away. Kernel objects are referenced counted and will generally linger on until all I/O involving those objects is complete.
That's why you can still get I/O notifications for a socket after it has been "destroyed" from your program's point of view. With sockets in particular, the shut down sequence will take place after you have closed your handle (because you did not explicitly shut down the socket before then).
Instead of destroying your Client object in response to a specific message, just close the socket handle and clean up your other structures in response to the abort notification. You might also consider doing a graceful disconnect rather than aborting the connection.
When I close connection on C++ client, I'm getting error code 64 on server (ERROR_NETNAME_DELETED) and all operations ends. But the browser won't close its sockets, so the connection descriptor stays in kernel. It is strange... I need to clear this descriptor somehow. If it happens in a singlethreaded server, I'm afraid to think what will be when I'll add some threads ))
– Iceman
Nov 20 '18 at 14:44
Indeed! I read about the closesocket function - it does not mean that the events associated with it will stop. So I just need to ignore these events?
– Iceman
Nov 20 '18 at 16:51
Possibly, but the fact that you apparently get multiple events for a single close is concerning. Like I said, I think some details are missing from the question.
– Peter Ruderman
Nov 20 '18 at 16:54
I also found the reason why the connection does not close from both sides. According to WebSocket specification, the browser waits for echo-close from server and don't terminates the connection instantly. )
– Iceman
Nov 21 '18 at 5:24
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53393101%2fgetqueuedcompletionstatus-continues-to-select-events-on-closed-sockets%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
I don't think you've included enough code to get a complete picture, but this line looks suspect:
switch( QCS * (BytesTransfered > 0) * Client->OpCode() ){
This is problematic for a couple of reasons. First, GetQueuedCompletionStatus
is not guaranteed to return 1 on success. MSDN promises only that it will return nonzero. Relying on a specific value for the success case is therefore risky. Second, you have no way to distinguish between a failed call and a successful call that returns 0 bytes. You should really separate your logic for managing the dequeue and for dispatching particular I/O events. This will make your code easier to understand and maintain.
You must also remember that there are two sides to every socket. There are the structures and socket handle you associate with it in user space, and then there are kernel objects that manage the low level details. Just because you close your handle on the user side does not mean that the kernel objects go away. Kernel objects are referenced counted and will generally linger on until all I/O involving those objects is complete.
That's why you can still get I/O notifications for a socket after it has been "destroyed" from your program's point of view. With sockets in particular, the shut down sequence will take place after you have closed your handle (because you did not explicitly shut down the socket before then).
Instead of destroying your Client object in response to a specific message, just close the socket handle and clean up your other structures in response to the abort notification. You might also consider doing a graceful disconnect rather than aborting the connection.
When I close connection on C++ client, I'm getting error code 64 on server (ERROR_NETNAME_DELETED) and all operations ends. But the browser won't close its sockets, so the connection descriptor stays in kernel. It is strange... I need to clear this descriptor somehow. If it happens in a singlethreaded server, I'm afraid to think what will be when I'll add some threads ))
– Iceman
Nov 20 '18 at 14:44
Indeed! I read about the closesocket function - it does not mean that the events associated with it will stop. So I just need to ignore these events?
– Iceman
Nov 20 '18 at 16:51
Possibly, but the fact that you apparently get multiple events for a single close is concerning. Like I said, I think some details are missing from the question.
– Peter Ruderman
Nov 20 '18 at 16:54
I also found the reason why the connection does not close from both sides. According to WebSocket specification, the browser waits for echo-close from server and don't terminates the connection instantly. )
– Iceman
Nov 21 '18 at 5:24
add a comment |
I don't think you've included enough code to get a complete picture, but this line looks suspect:
switch( QCS * (BytesTransfered > 0) * Client->OpCode() ){
This is problematic for a couple of reasons. First, GetQueuedCompletionStatus
is not guaranteed to return 1 on success. MSDN promises only that it will return nonzero. Relying on a specific value for the success case is therefore risky. Second, you have no way to distinguish between a failed call and a successful call that returns 0 bytes. You should really separate your logic for managing the dequeue and for dispatching particular I/O events. This will make your code easier to understand and maintain.
You must also remember that there are two sides to every socket. There are the structures and socket handle you associate with it in user space, and then there are kernel objects that manage the low level details. Just because you close your handle on the user side does not mean that the kernel objects go away. Kernel objects are referenced counted and will generally linger on until all I/O involving those objects is complete.
That's why you can still get I/O notifications for a socket after it has been "destroyed" from your program's point of view. With sockets in particular, the shut down sequence will take place after you have closed your handle (because you did not explicitly shut down the socket before then).
Instead of destroying your Client object in response to a specific message, just close the socket handle and clean up your other structures in response to the abort notification. You might also consider doing a graceful disconnect rather than aborting the connection.
When I close connection on C++ client, I'm getting error code 64 on server (ERROR_NETNAME_DELETED) and all operations ends. But the browser won't close its sockets, so the connection descriptor stays in kernel. It is strange... I need to clear this descriptor somehow. If it happens in a singlethreaded server, I'm afraid to think what will be when I'll add some threads ))
– Iceman
Nov 20 '18 at 14:44
Indeed! I read about the closesocket function - it does not mean that the events associated with it will stop. So I just need to ignore these events?
– Iceman
Nov 20 '18 at 16:51
Possibly, but the fact that you apparently get multiple events for a single close is concerning. Like I said, I think some details are missing from the question.
– Peter Ruderman
Nov 20 '18 at 16:54
I also found the reason why the connection does not close from both sides. According to WebSocket specification, the browser waits for echo-close from server and don't terminates the connection instantly. )
– Iceman
Nov 21 '18 at 5:24
add a comment |
I don't think you've included enough code to get a complete picture, but this line looks suspect:
switch( QCS * (BytesTransfered > 0) * Client->OpCode() ){
This is problematic for a couple of reasons. First, GetQueuedCompletionStatus
is not guaranteed to return 1 on success. MSDN promises only that it will return nonzero. Relying on a specific value for the success case is therefore risky. Second, you have no way to distinguish between a failed call and a successful call that returns 0 bytes. You should really separate your logic for managing the dequeue and for dispatching particular I/O events. This will make your code easier to understand and maintain.
You must also remember that there are two sides to every socket. There are the structures and socket handle you associate with it in user space, and then there are kernel objects that manage the low level details. Just because you close your handle on the user side does not mean that the kernel objects go away. Kernel objects are referenced counted and will generally linger on until all I/O involving those objects is complete.
That's why you can still get I/O notifications for a socket after it has been "destroyed" from your program's point of view. With sockets in particular, the shut down sequence will take place after you have closed your handle (because you did not explicitly shut down the socket before then).
Instead of destroying your Client object in response to a specific message, just close the socket handle and clean up your other structures in response to the abort notification. You might also consider doing a graceful disconnect rather than aborting the connection.
I don't think you've included enough code to get a complete picture, but this line looks suspect:
switch( QCS * (BytesTransfered > 0) * Client->OpCode() ){
This is problematic for a couple of reasons. First, GetQueuedCompletionStatus
is not guaranteed to return 1 on success. MSDN promises only that it will return nonzero. Relying on a specific value for the success case is therefore risky. Second, you have no way to distinguish between a failed call and a successful call that returns 0 bytes. You should really separate your logic for managing the dequeue and for dispatching particular I/O events. This will make your code easier to understand and maintain.
You must also remember that there are two sides to every socket. There are the structures and socket handle you associate with it in user space, and then there are kernel objects that manage the low level details. Just because you close your handle on the user side does not mean that the kernel objects go away. Kernel objects are referenced counted and will generally linger on until all I/O involving those objects is complete.
That's why you can still get I/O notifications for a socket after it has been "destroyed" from your program's point of view. With sockets in particular, the shut down sequence will take place after you have closed your handle (because you did not explicitly shut down the socket before then).
Instead of destroying your Client object in response to a specific message, just close the socket handle and clean up your other structures in response to the abort notification. You might also consider doing a graceful disconnect rather than aborting the connection.
answered Nov 20 '18 at 14:22
Peter RudermanPeter Ruderman
10.2k2352
10.2k2352
When I close connection on C++ client, I'm getting error code 64 on server (ERROR_NETNAME_DELETED) and all operations ends. But the browser won't close its sockets, so the connection descriptor stays in kernel. It is strange... I need to clear this descriptor somehow. If it happens in a singlethreaded server, I'm afraid to think what will be when I'll add some threads ))
– Iceman
Nov 20 '18 at 14:44
Indeed! I read about the closesocket function - it does not mean that the events associated with it will stop. So I just need to ignore these events?
– Iceman
Nov 20 '18 at 16:51
Possibly, but the fact that you apparently get multiple events for a single close is concerning. Like I said, I think some details are missing from the question.
– Peter Ruderman
Nov 20 '18 at 16:54
I also found the reason why the connection does not close from both sides. According to WebSocket specification, the browser waits for echo-close from server and don't terminates the connection instantly. )
– Iceman
Nov 21 '18 at 5:24
add a comment |
When I close connection on C++ client, I'm getting error code 64 on server (ERROR_NETNAME_DELETED) and all operations ends. But the browser won't close its sockets, so the connection descriptor stays in kernel. It is strange... I need to clear this descriptor somehow. If it happens in a singlethreaded server, I'm afraid to think what will be when I'll add some threads ))
– Iceman
Nov 20 '18 at 14:44
Indeed! I read about the closesocket function - it does not mean that the events associated with it will stop. So I just need to ignore these events?
– Iceman
Nov 20 '18 at 16:51
Possibly, but the fact that you apparently get multiple events for a single close is concerning. Like I said, I think some details are missing from the question.
– Peter Ruderman
Nov 20 '18 at 16:54
I also found the reason why the connection does not close from both sides. According to WebSocket specification, the browser waits for echo-close from server and don't terminates the connection instantly. )
– Iceman
Nov 21 '18 at 5:24
When I close connection on C++ client, I'm getting error code 64 on server (ERROR_NETNAME_DELETED) and all operations ends. But the browser won't close its sockets, so the connection descriptor stays in kernel. It is strange... I need to clear this descriptor somehow. If it happens in a singlethreaded server, I'm afraid to think what will be when I'll add some threads ))
– Iceman
Nov 20 '18 at 14:44
When I close connection on C++ client, I'm getting error code 64 on server (ERROR_NETNAME_DELETED) and all operations ends. But the browser won't close its sockets, so the connection descriptor stays in kernel. It is strange... I need to clear this descriptor somehow. If it happens in a singlethreaded server, I'm afraid to think what will be when I'll add some threads ))
– Iceman
Nov 20 '18 at 14:44
Indeed! I read about the closesocket function - it does not mean that the events associated with it will stop. So I just need to ignore these events?
– Iceman
Nov 20 '18 at 16:51
Indeed! I read about the closesocket function - it does not mean that the events associated with it will stop. So I just need to ignore these events?
– Iceman
Nov 20 '18 at 16:51
Possibly, but the fact that you apparently get multiple events for a single close is concerning. Like I said, I think some details are missing from the question.
– Peter Ruderman
Nov 20 '18 at 16:54
Possibly, but the fact that you apparently get multiple events for a single close is concerning. Like I said, I think some details are missing from the question.
– Peter Ruderman
Nov 20 '18 at 16:54
I also found the reason why the connection does not close from both sides. According to WebSocket specification, the browser waits for echo-close from server and don't terminates the connection instantly. )
– Iceman
Nov 21 '18 at 5:24
I also found the reason why the connection does not close from both sides. According to WebSocket specification, the browser waits for echo-close from server and don't terminates the connection instantly. )
– Iceman
Nov 21 '18 at 5:24
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53393101%2fgetqueuedcompletionstatus-continues-to-select-events-on-closed-sockets%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown